Vector* Vector_vcreate(unsigned count, va_list args) { return Vector_new(ArgList_vcreate(count, args)); }
// Note I didn't implement the stable id fetching uggliness here. I'll probably make a separate method for that // if necessary Vector *BaseAdaptor_uncachedFetchAllByDbIDList(BaseAdaptor *ba, Vector *idList, Slice *slice) { if ( idList == NULL) { fprintf(stderr, "id_list list reference argument is required - bye!"); return NULL; } char constraintPref[1024]; if (!Vector_getNumElement(idList)) { return Vector_new(); } NameTableType *tables = ba->getTables(); char **t = (*tables)[0]; sprintf(constraintPref, "%s.%s_id ", t[SYN], t[NAME] ); // Ensure that we do not exceed MySQL's max_allowed_packet (defaults to // 1 MB) splitting large queries into smaller queries of at most 256 KB. // Assuming a (generous) average dbID string // length of 16, this means 16384 dbIDs in each query. int maxSize = 16384; // Uniquify the list IDHash *idListHash = IDHash_new(IDHASH_MEDIUM); int i; for (i=0; i<Vector_getNumElement(idList); i++) { IDType id = *(IDType *)(Vector_getElementAt(idList, i)); if (!IDHash_contains(idListHash, id)) { IDHash_add(idListHash, id, &trueVal); } } IDType *uniqueIds = IDHash_getKeys(idListHash); int nUniqueId = IDHash_getNumValues(idListHash); IDHash_free(idListHash, NULL); Vector *out = Vector_new(); int lenNum; for (i=0; i<nUniqueId; i+=maxSize) { char *constraint = NULL; if ((constraint = (char *)calloc(655500,sizeof(char))) == NULL) { fprintf(stderr,"Failed allocating constraint\n"); return out; } strcpy(constraint, constraintPref); // Special case for one remaining Id if (i == nUniqueId-1) { sprintf(constraint, "%s = "IDFMTSTR, constraint, uniqueIds[i]); } else { char tmpStr[1024]; int endPoint = sprintf(constraint, "%s IN (", constraint); int j; for (j=0; j<maxSize && j+i<nUniqueId; j++) { if (j!=0) { constraint[endPoint++] = ','; constraint[endPoint++] = ' '; } lenNum = sprintf(tmpStr, IDFMTSTR, uniqueIds[i+j]); memcpy(&(constraint[endPoint]), tmpStr, lenNum); endPoint+=lenNum; } constraint[endPoint++] = ')'; constraint[endPoint] = '\0'; } Vector *resChunk = BaseAdaptor_genericFetch(ba, constraint, NULL, slice); Vector_append(out, resChunk); Vector_free(resChunk); free(constraint); } free(uniqueIds); return out; }
Value* Vector_eval(Vector* vec, Context* ctx) { return ValVec(Vector_new(ArgList_eval(vec->vals, ctx))); }
void vm_exec(VM *vm, bool trace) { int a = 0; int i = 0; bool b1, b2; float f,g; char* c; PVector_ptr vptr,r,l; int x, y; Activation_Record *frame; Function_metadata *const main = vm_function(vm, "main"); vm_call(vm, main); // Define VM registers (C compiler probably ignores 'register' nowadays // but it's good documentation in this case. Keep as locals for // convenience but write them back to the vm object after each decode/execute. register addr32 ip = vm->ip; register int sp = vm->sp; register int fp = vm->fp; const byte *code = vm->code; element *stack = vm->stack; int opcode = code[ip]; while (opcode != HALT && ip < vm->code_size ) { if (trace) vm_print_instr(vm, ip); ip++; switch (opcode) { case IADD: validate_stack_address(sp-1); y = stack[sp--].i; x = stack[sp].i; stack[sp].i = x + y; break; case ISUB: validate_stack_address(sp-1); y = stack[sp--].i; x = stack[sp].i; stack[sp].i = x - y; break; case IMUL: validate_stack_address(sp-1); y = stack[sp--].i; x = stack[sp].i; stack[sp].i = x * y; break; case IDIV: validate_stack_address(sp-1); y = stack[sp--].i; x = stack[sp].i; if (y ==0 ) { zero_division_error(); break; } stack[sp].i = x / y; break; case FADD: validate_stack_address(sp-1); f = stack[sp--].f; g = stack[sp].f; stack[sp].f = g + f; break; case FSUB: validate_stack_address(sp-1); f = stack[sp--].f; g = stack[sp].f; stack[sp].f = g - f; break; case FMUL: validate_stack_address(sp-1); f = stack[sp--].f; g = stack[sp].f; stack[sp].f = g * f; break; case FDIV: validate_stack_address(sp-1); f = stack[sp--].f; g = stack[sp].f; if (f == 0) { zero_division_error(); break; } stack[sp].f = g / f; break; case VADD: validate_stack_address(sp-1); r = stack[sp--].vptr; l = stack[sp].vptr; vptr = Vector_add(l,r); stack[sp].vptr = vptr; break; case VADDI: validate_stack_address(sp-1); i = stack[sp--].i; vptr = stack[sp].vptr; vptr = Vector_add(vptr,Vector_from_int(i,vptr.vector->length)); stack[sp].vptr = vptr; break; case VADDF: validate_stack_address(sp-1); f = stack[sp--].f; vptr = stack[sp].vptr; vptr = Vector_add(vptr,Vector_from_float(f,vptr.vector->length)); stack[sp].vptr = vptr; break; case VSUB: validate_stack_address(sp-1); r = stack[sp--].vptr; l = stack[sp].vptr; vptr = Vector_sub(l,r); stack[sp].vptr = vptr; break; case VSUBI: validate_stack_address(sp-1); i = stack[sp--].i; vptr = stack[sp].vptr; vptr = Vector_sub(vptr,Vector_from_int(i,vptr.vector->length)); stack[sp].vptr = vptr; break; case VSUBF: validate_stack_address(sp-1); f = stack[sp--].f; vptr = stack[sp].vptr; vptr = Vector_sub(vptr,Vector_from_float(f,vptr.vector->length)); stack[sp].vptr = vptr; break; case VMUL: validate_stack_address(sp-1); r = stack[sp--].vptr; l = stack[sp].vptr; vptr = Vector_mul(l,r); stack[sp].vptr = vptr; break; case VMULI: validate_stack_address(sp-1); i = stack[sp--].i; vptr = stack[sp].vptr; vptr = Vector_mul(vptr,Vector_from_int(i,vptr.vector->length)); stack[sp].vptr = vptr; break; case VMULF: validate_stack_address(sp-1); f = stack[sp--].f; vptr = stack[sp].vptr; vptr = Vector_mul(vptr,Vector_from_float(f,vptr.vector->length)); stack[sp].vptr = vptr; break; case VDIV: validate_stack_address(sp-1); r = stack[sp--].vptr; l = stack[sp].vptr; vptr = Vector_div(l,r); stack[sp].vptr = vptr; break; case VDIVI: validate_stack_address(sp-1); i = stack[sp--].i; if (i == 0) { zero_division_error(); break; } vptr = stack[sp].vptr; vptr = Vector_div(vptr,Vector_from_int(i,vptr.vector->length)); stack[sp].vptr = vptr; break; case VDIVF: validate_stack_address(sp-1); f = stack[sp--].f; if (f == 0) { zero_division_error(); break; } vptr = stack[sp].vptr; vptr = Vector_div(vptr,Vector_from_float(f,vptr.vector->length)); stack[sp].vptr = vptr; break; case SADD: validate_stack_address(sp-1); char * right = stack[sp--].s; stack[sp].s = String_add(String_new(stack[sp].s),String_new(right))->str; break; case OR : validate_stack_address(sp-1); b2 = stack[sp--].b; b1 = stack[sp].b; stack[sp].b = b1 || b2; break; case AND : validate_stack_address(sp-1); b2 = stack[sp--].b; b1 = stack[sp].b; stack[sp].b = b1 && b2; break; case INEG: validate_stack_address(sp); stack[sp].i = -stack[sp].i; break; case FNEG: validate_stack_address(sp); stack[sp].f = -stack[sp].f; break; case NOT: validate_stack_address(sp); stack[sp].b = !stack[sp].b; break; case I2F: validate_stack_address(sp); stack[sp].f = stack[sp].i; break; case I2S: validate_stack_address(sp); stack[sp].s = String_from_int(stack[sp].i)->str; break; case F2I: validate_stack_address(sp); stack[sp].i = (int)stack[sp].f; break; case F2S: validate_stack_address(sp); stack[sp].s = String_from_float((float)stack[sp].f)->str; break; case V2S: validate_stack_address(sp); vptr = stack[sp].vptr; stack[sp].s = String_from_vector(vptr)->str; break; case IEQ: validate_stack_address(sp-1); y = stack[sp--].i; x = stack[sp].i; stack[sp].b = x == y; break; case INEQ: validate_stack_address(sp-1); y = stack[sp--].i; x = stack[sp].i; stack[sp].b = x != y; break; case ILT: validate_stack_address(sp-1); y = stack[sp--].i; x = stack[sp].i; stack[sp].b = x < y; break; case ILE: validate_stack_address(sp-1); y = stack[sp--].i; x = stack[sp].i; stack[sp].b = x <= y; break; case IGT: validate_stack_address(sp-1); y = stack[sp--].i; x = stack[sp].i; stack[sp].b = x > y; break; case IGE: validate_stack_address(sp-1); y = stack[sp--].i; x = stack[sp].i; stack[sp].b = x >= y; break; case FEQ: validate_stack_address(sp-1); g = stack[sp--].f; f = stack[sp].f; stack[sp].b = f == g; break; case FNEQ: validate_stack_address(sp-1); g = stack[sp--].f; f = stack[sp].f; stack[sp].b = f != g; break; case FLT: validate_stack_address(sp-1); g = stack[sp--].f; f = stack[sp].f; stack[sp].b = f < g; break; case FLE: validate_stack_address(sp-1); g = stack[sp--].f; f = stack[sp].f; stack[sp].b = f <= g; break; case FGT: validate_stack_address(sp-1); g = stack[sp--].f; f = stack[sp].f; stack[sp].b = f > g; break; case FGE: validate_stack_address(sp-1); g = stack[sp--].f; f = stack[sp].f; stack[sp].b = f >= g; break; case SEQ: validate_stack_address(sp-1); c = stack[sp--].s; b1 = String_eq(String_new(stack[sp--].s),String_new(c)); stack[++sp].b = b1; break; case SNEQ: validate_stack_address(sp-1); c = stack[sp--].s; b1 = String_neq(String_new(stack[sp--].s),String_new(c)); stack[++sp].b = b1; break; case SGT: validate_stack_address(sp-1); c = stack[sp--].s; b1 = String_gt(String_new(stack[sp--].s),String_new(c)); stack[++sp].b = b1; break; case SGE: validate_stack_address(sp-1); c = stack[sp--].s; b1 = String_ge(String_new(stack[sp--].s),String_new(c)); stack[++sp].b = b1; break; case SLT: validate_stack_address(sp-1); c = stack[sp--].s; b1 = String_lt(String_new(stack[sp--].s),String_new(c)); stack[++sp].b = b1; break; case SLE: validate_stack_address(sp-1); c = stack[sp--].s; b1 = String_le(String_new(stack[sp--].s),String_new(c)); stack[++sp].b = b1; break; case VEQ: validate_stack_address(sp-1); l = stack[sp--].vptr; r = stack[sp--].vptr; b1 = Vector_eq(l,r); stack[++sp].b = b1; break; case VNEQ: validate_stack_address(sp-1); l = stack[sp--].vptr; r = stack[sp--].vptr; b1 = Vector_neq(l,r); stack[++sp].b = b1; break; case BR: ip += int16(code,ip) - 1; break; case BRF: validate_stack_address(sp); if ( !stack[sp--].b ) { int offset = int16(code,ip); ip += offset - 1; } else { ip += 2; } break; case ICONST: stack[++sp].i = int32(code,ip); ip += 4; break; case FCONST: stack[++sp].f = float32(code,ip); ip += 4; break; case SCONST : i = int16(code,ip); ip += 2; stack[++sp].s = vm->strings[i]; break; case ILOAD: i = int16(code,ip); ip += 2; stack[++sp].i = vm->call_stack[vm->callsp].locals[i].i; break; case FLOAD: i = int16(code,ip); ip += 2; stack[++sp].f = vm->call_stack[vm->callsp].locals[i].f; break; case VLOAD: i = int16(code,ip); ip += 2; stack[++sp].vptr = vm->call_stack[vm->callsp].locals[i].vptr; break; case SLOAD: i = int16(code,ip); ip += 2; stack[++sp].s = vm->call_stack[vm->callsp].locals[i].s; break; case STORE: i = int16(code,ip); ip += 2; vm->call_stack[vm->callsp].locals[i] = stack[sp--]; // untyped store; it'll just copy all bits break; case VECTOR: i = stack[sp--].i; validate_stack_address(sp-i+1); double *data = (double*)malloc(i*sizeof(double)); for (int j = i-1; j >= 0;j--) { data[j] = stack[sp--].f; } vptr = Vector_new(data,i); stack[++sp].vptr = vptr; break; case VLOAD_INDEX: i = stack[sp--].i; vptr = stack[sp--].vptr; vm->stack[++sp].f = ith(vptr, i-1); break; case STORE_INDEX: f = stack[sp--].f; i = stack[sp--].i; vptr = stack[sp--].vptr; set_ith(vptr, i-1, f); break; case SLOAD_INDEX: i = stack[sp--].i; if (i-1 >= strlen(stack[sp].s)) { fprintf(stderr, "StringIndexOutOfRange: %d\n",(int)strlen(stack[sp].s)); break; } c = String_from_char(stack[sp--].s[i-1])->str; stack[++sp].s = c; break; case PUSH_DFLT_RETV: i = *&vm->call_stack[vm->callsp].func->return_type; sp = push_default_value(i, sp, stack); break; case POP: sp--; break; case CALL: a = int16(code,ip); // load index of function from code memory WRITE_BACK_REGISTERS(vm); // (ip has been updated) vm_call(vm, &vm->functions[a]); LOAD_REGISTERS(vm); break; case RET: frame = &vm->call_stack[vm->callsp--]; ip = frame->retaddr; break; case IPRINT: validate_stack_address(sp); printf("%d\n", stack[sp--].i); break; case FPRINT: validate_stack_address(sp); printf("%1.2f\n", stack[sp--].f); break; case BPRINT: validate_stack_address(sp); printf("%d\n", stack[sp--].b); break; case SPRINT: validate_stack_address(sp); printf("%s\n", stack[sp--].s); break; case VPRINT: validate_stack_address(sp); print_vector(stack[sp--].vptr); break; case VLEN: vptr = stack[sp--].vptr; i = Vector_len(vptr); stack[++sp].i = i; break; case SLEN: c = stack[sp--].s; i = String_len(String_new(c)); stack[++sp].i = i; break; case GC_START: vm->call_stack[vm->callsp].save_gc_roots = gc_num_roots(); break; case GC_END: gc_set_num_roots(vm->call_stack[vm->callsp].save_gc_roots); break; case SROOT: gc_add_root((void **)&stack[sp].s); break; case VROOT: gc_add_root((void **)&stack[sp].vptr); break; case COPY_VECTOR: if (vm->call_stack[vm->callsp].locals[i].vptr.vector != NULL) { stack[sp].vptr = Vector_copy(vm->call_stack[vm->callsp].locals[i].vptr); } else if (stack[sp].vptr.vector != NULL) { stack[sp].vptr = Vector_copy(stack[sp].vptr); } else { fprintf(stderr, "Vector reference cannot be found\n"); } break; case NOP : break; default: printf("invalid opcode: %d at ip=%d\n", opcode, (ip - 1)); exit(1); } WRITE_BACK_REGISTERS(vm); if (trace) vm_print_stack(vm); opcode = code[ip]; } if (trace) vm_print_instr(vm, ip); if (trace) vm_print_stack(vm); gc_check(); }
VALUE VM_run(STATE) { Debugger_load_current_file(state); int *ip = CURR_FRAME->fn->code; while(1) { switch(*ip) { case NOOP: break; case SETLINE: { // debugging ip++; Debugger_setline(state, *ip); break; } case PUSH: { Debugger_evaluate(state); ip++; debugi("PUSH %i", *ip); VALUE value = LITERAL(*ip); Stack_push(STACK, value); break; } case PUSHTRUE: { Debugger_evaluate(state); debugi("PUSHTRUE"); Stack_push(STACK, TrueObject); break; } case PUSHFALSE: { Debugger_evaluate(state); debugi("PUSHFALSE"); Stack_push(STACK, FalseObject); break; } case PUSHNIL: { Debugger_evaluate(state); debugi("PUSHNIL"); Stack_push(STACK, NilObject); break; } case JMP: { Debugger_evaluate(state); ip++; int jump = *ip; debugi("JMP %i", jump); while(jump--) ip++; break; } case JIF: { Debugger_evaluate(state); ip++; int jump = *ip; debugi("JIF %i", jump); VALUE value = Stack_pop(STACK); if (value == FalseObject || value == NilObject) { while(jump--) ip++; } break; } case JIT: { Debugger_evaluate(state); ip++; int jump = *ip; debugi("JIT %i", jump); VALUE value = Stack_pop(STACK); if (value != FalseObject && value != NilObject) { while(jump--) ip++; } break; } case GOTO: { Debugger_evaluate(state); ip++; int jump = *ip - 2; debugi("GOTO %i", jump); ip = CURR_FRAME->fn->code; while(jump--) ip++; break; } case GETSLOT: { Debugger_evaluate(state); ip++; debugi("GETSLOT %i", *ip); VALUE receiver = Stack_pop(STACK); VALUE slot = LITERAL(*ip); check(receiver->type != NilType, "Tried to get a slot from nil."); check(slot->type == StringType, "Slot name must be a String."); VALUE value = Value_get(receiver, VAL2STR(slot)); check(value, "Undefined slot %s on object type %i.", VAL2STR(slot), receiver->type); Stack_push(STACK, value); break; } case SETSLOT: { Debugger_evaluate(state); ip++; debugi("SETSLOT %i", *ip); VALUE value = Stack_pop(STACK); VALUE receiver = Stack_pop(STACK); VALUE slot = LITERAL(*ip); check(receiver->type != NilType, "Tried to set a slot on nil."); check(slot->type == StringType, "Slot name must be a String."); Value_set(state, receiver, VAL2STR(slot), value); Stack_push(STACK, value); // push the rhs back to the stack break; } case DEFN: { Debugger_evaluate(state); ip++; debugi("DEFN %i", *ip); VALUE fn_name = LITERAL(*ip); bstring state_fn = bfromcstr(VAL2STR(fn_name)); VALUE closure = Closure_new(state, STATE_FN(state_fn), CURR_FRAME); bdestroy(state_fn); Stack_push(STACK, closure); break; } case MAKEVEC: { Debugger_evaluate(state); ip++; debugi("MAKEVEC %i", *ip); int count = *ip; DArray *array = DArray_create(sizeof(VALUE), count || 1); while(count--) { VALUE elem = Stack_pop(STACK); check(elem, "Stack underflow."); GC_protect(elem); DArray_push(array, elem); } VALUE vector = Vector_new(state, array); Stack_push(STACK, vector); Vector_each(vector, ^ void (VALUE element) { GC_unprotect(element); }); break; } case SEND: { Debugger_evaluate(state); ip++; int op1 = *ip; ip++; int op2 = *ip; debugi("SEND %i %i", op1, op2); VALUE name = LITERAL(op1); int argcount = op2; DArray *locals = DArray_create(sizeof(VALUE), argcount+1); while(argcount--) { DArray_push(locals, Stack_pop(STACK)); } VALUE receiver = Stack_pop(STACK); // Special chicken-egg case. We cannot define "apply" as a native method // on Closure, since that triggers the creation of a new closure ad // infinitum, so we have to handle this special function here. if(receiver->type == ClosureType && strcmp(VAL2STR(name), "apply") == 0) { state->ret = ip; // save where we want to return ip = Function_call(state, VAL2FN(receiver), CURR_FRAME->self, locals, VAL2STR(name)); break; } VALUE closure = Value_get(receiver, VAL2STR(name)); check(closure, "Undefined slot %s on object type %i.", VAL2STR(name), receiver->type); if (closure->type != ClosureType && closure != NilObject) { // GETSLOT Stack_push(STACK, closure); DArray_destroy(locals); break; } #ifdef OPTIMIZE_SEND if(op2 == 1 && strcmp(VAL2STR(name), "[]") == 0) { // getslot VALUE key = (VALUE)DArray_at(locals, 0); Stack_push(STACK, Value_get(receiver, VAL2STR(key))); DArray_destroy(locals); break; } if(op2 == 2 && strcmp(VAL2STR(name), "[]=") == 0) { // setslot VALUE key = (VALUE)DArray_at(locals, 0); VALUE value = (VALUE)DArray_at(locals, 1); Value_set(receiver, VAL2STR(key), value); Stack_push(STACK, value); DArray_destroy(locals); break; } #endif state->ret = ip; // save where we want to return ip = Function_call(state, VAL2FN(closure), receiver, locals, VAL2STR(name)); break; } case PUSHLOBBY: { Debugger_evaluate(state); debugi("PUSHLOBBY"); Stack_push(STACK, state->lobby); break; } case PUSHSELF: { Debugger_evaluate(state); debugi("PUSHSELF"); Stack_push(STACK, CURR_FRAME->self); break; } case PUSHLOCAL: { Debugger_evaluate(state); ip++; Stack_push(STACK, LOCAL(*ip)); debugi("PUSHLOCAL %i", *ip); break; } case PUSHLOCALDEPTH: { Debugger_evaluate(state); ip++; int depth = *ip; ip++; Stack_push(STACK, DEEPLOCAL(depth, *ip)); debugi("PUSHLOCALDEPTH %i %i", depth, *ip); break; } case SETLOCAL: { Debugger_evaluate(state); ip++; debugi("SETLOCAL %i", *ip); LOCALSET(*ip, Stack_peek(STACK)); break; } case SETLOCALDEPTH: { Debugger_evaluate(state); ip++; int depth = *ip; ip++; debugi("SETLOCAL %i %i", depth, *ip); DEEPLOCALSET(depth, *ip, Stack_peek(STACK)); break; } case POP: { Debugger_evaluate(state); ip++; int count = *ip; debugi("POP %i", count); check(Stack_count(STACK) >= count, "Stack underflow."); while(count--) Stack_pop(STACK); break; } case RET: { Debugger_evaluate(state); debugi("RET"); CallFrame *old_frame = Stack_pop(FRAMES); ip = old_frame->ret; CallFrame_destroy(old_frame); check(Stack_count(STACK) > 0, "Stack underflow."); if (ip == NULL) return Stack_pop(STACK); // if there's nowhere to return, exit break; } case DUMP: { Debugger_evaluate(state); debugi("DUMP"); Stack_print(state, STACK); DArray *literals = CURR_FRAME->fn->literals; printf("--LITERALS (%i)--\n", DArray_count(literals)); Value_print_all(state, literals); DArray *locals = CURR_FRAME->locals; printf("--LOCALS (%i)--\n", DArray_count(locals)); Value_print_all(state, locals); break; } }
Vector sub(Vector a, Vector b) { return Vector_new(a.x - b.x, a.y - b.y, a.z - b.z); }
Vector cross(Vector a, Vector b) { return Vector_new(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x); }
Vector *PredictionTranscriptAdaptor_fetchAllBySlice(PredictionTranscriptAdaptor *pta, Slice *slice, char *logicName, int loadExons) { //my $transcripts = $self->SUPER::fetch_all_by_Slice($slice,$logic_name); Vector *transcripts = BaseFeatureAdaptor_fetchAllBySlice((BaseFeatureAdaptor *)pta, slice, logicName); // if there are 0 or 1 transcripts still do lazy-loading if ( ! loadExons || Vector_getNumElement(transcripts) < 2 ) { return transcripts; } // preload all of the exons now, instead of lazy loading later // faster than 1 query per transcript // get extent of region spanned by transcripts long minStart = 2000000000; long maxEnd = -2000000000; int i; for (i=0; i<Vector_getNumElement(transcripts); i++) { PredictionTranscript *t = Vector_getElementAt(transcripts, i); if (PredictionTranscript_getSeqRegionStart((SeqFeature*)t) < minStart) { minStart = PredictionTranscript_getSeqRegionStart((SeqFeature*)t); } if (PredictionTranscript_getSeqRegionEnd((SeqFeature*)t) > maxEnd) { maxEnd = PredictionTranscript_getSeqRegionEnd((SeqFeature*)t); } } Slice *extSlice; if (minStart >= Slice_getStart(slice) && maxEnd <= Slice_getEnd(slice)) { extSlice = slice; } else { SliceAdaptor *sa = DBAdaptor_getSliceAdaptor(pta->dba); extSlice = SliceAdaptor_fetchByRegion(sa, Slice_getCoordSystemName(slice), Slice_getSeqRegionName(slice), minStart, maxEnd, Slice_getStrand(slice), CoordSystem_getVersion(Slice_getCoordSystem(slice)), 0); } // associate exon identifiers with transcripts IDHash *trHash = IDHash_new(IDHASH_MEDIUM); for (i=0; i<Vector_getNumElement(transcripts); i++) { PredictionTranscript *t = Vector_getElementAt(transcripts, i); if ( ! IDHash_contains(trHash, PredictionTranscript_getDbID(t))) { IDHash_add(trHash, PredictionTranscript_getDbID(t), t); } } IDType *uniqueIds = IDHash_getKeys(trHash); char tmpStr[1024]; char *qStr = NULL; if ((qStr = (char *)calloc(655500,sizeof(char))) == NULL) { fprintf(stderr,"Failed allocating qStr\n"); return transcripts; } int lenNum; int endPoint = sprintf(qStr, "SELECT prediction_transcript_id, prediction_exon_id, exon_rank FROM prediction_exon WHERE prediction_transcript_id IN ("); for (i=0; i<IDHash_getNumValues(trHash); i++) { if (i!=0) { qStr[endPoint++] = ','; qStr[endPoint++] = ' '; } lenNum = sprintf(tmpStr,IDFMTSTR,uniqueIds[i]); memcpy(&(qStr[endPoint]), tmpStr, lenNum); endPoint+=lenNum; } qStr[endPoint++] = ')'; qStr[endPoint] = '\0'; free(uniqueIds); StatementHandle *sth = pta->prepare((BaseAdaptor *)pta,qStr,strlen(qStr)); sth->execute(sth); IDHash *exTrHash = IDHash_new(IDHASH_MEDIUM); ResultRow *row; while ((row = sth->fetchRow(sth))) { IDType trId = row->getLongLongAt(row,0); IDType exId = row->getLongLongAt(row,1); int rank = row->getIntAt(row,2); if (! IDHash_contains(exTrHash, exId)) { Vector *vec = Vector_new(); Vector_setFreeFunc(vec, PredictionTranscriptRankPair_free); IDHash_add(exTrHash, exId, vec); } Vector *exVec = IDHash_getValue(exTrHash, exId); PredictionTranscriptRankPair *trp = PredictionTranscriptRankPair_new(IDHash_getValue(trHash, trId), rank); Vector_addElement(exVec, trp); } IDHash_free(trHash, NULL); sth->finish(sth); PredictionExonAdaptor *pea = DBAdaptor_getPredictionExonAdaptor(pta->dba); Vector *exons = PredictionExonAdaptor_fetchAllBySlice(pea, extSlice); // move exons onto transcript slice, and add them to transcripts for (i=0; i<Vector_getNumElement(exons); i++) { PredictionExon *ex = Vector_getElementAt(exons, i); // Perl didn't have this line - it was in GeneAdaptor version so I think I'm going to keep it if (!IDHash_contains(exTrHash, PredictionExon_getDbID(ex))) continue; PredictionExon *newEx; if (slice != extSlice) { newEx = (PredictionExon*)PredictionExon_transfer((SeqFeature*)ex, slice); if (newEx == NULL) { fprintf(stderr, "Unexpected. Exon could not be transferred onto PredictionTranscript slice.\n"); exit(1); } } else { newEx = ex; } Vector *exVec = IDHash_getValue(exTrHash, PredictionExon_getDbID(newEx)); int j; for (j=0; j<Vector_getNumElement(exVec); j++) { PredictionTranscriptRankPair *trp = Vector_getElementAt(exVec, j); PredictionTranscript_addExon(trp->transcript, newEx, &trp->rank); } } IDHash_free(exTrHash, Vector_free); free(qStr); return transcripts; }
/* =head2 _objs_from_sth Arg [1] : DBI:st $sth An executed DBI statement handle Arg [2] : (optional) Bio::EnsEMBL::Mapper $mapper An mapper to be used to convert contig coordinates to assembly coordinates. Arg [3] : (optional) Bio::EnsEMBL::Slice $slice A slice to map the prediction transcript to. Example : $p_transcripts = $self->_objs_from_sth($sth); Description: Creates a list of Prediction transcripts from an executed DBI statement handle. The columns retrieved via the statement handle must be in the same order as the columns defined by the _columns method. If the slice argument is provided then the the prediction transcripts will be in returned in the coordinate system of the $slice argument. Otherwise the prediction transcripts will be returned in the RawContig coordinate system. Returntype : reference to a list of Bio::EnsEMBL::PredictionTranscripts Exceptions : none Caller : superclass generic_fetch Status : Stable =cut */ Vector *PredictionTranscriptAdaptor_objectsFromStatementHandle(PredictionTranscriptAdaptor *pta, StatementHandle *sth, AssemblyMapper *assMapper, Slice *destSlice) { SliceAdaptor *sa = DBAdaptor_getSliceAdaptor(pta->dba); AnalysisAdaptor *aa = DBAdaptor_getAnalysisAdaptor(pta->dba); Vector *pTranscripts = Vector_new(); IDHash *sliceHash = IDHash_new(IDHASH_SMALL); long destSliceStart; long destSliceEnd; int destSliceStrand; long destSliceLength; char * destSliceSrName; IDType destSliceSrId = 0; if (destSlice) { destSliceStart = Slice_getStart(destSlice); destSliceEnd = Slice_getEnd(destSlice); destSliceStrand = Slice_getStrand(destSlice); destSliceLength = Slice_getLength(destSlice); destSliceSrName = Slice_getSeqRegionName(destSlice); destSliceSrId = Slice_getSeqRegionId(destSlice); } ResultRow *row; while ((row = sth->fetchRow(sth))) { IDType predictionTranscriptId = row->getLongLongAt(row,0); IDType seqRegionId = row->getLongLongAt(row,1); long seqRegionStart = row->getLongAt(row,2); long seqRegionEnd = row->getLongAt(row,3); int seqRegionStrand = row->getIntAt(row,4); IDType analysisId = row->getLongLongAt(row,5); char *displayLabel = row->getStringAt(row,6); // get the analysis object Analysis *analysis = AnalysisAdaptor_fetchByDbID(aa, analysisId); if (! IDHash_contains(sliceHash, seqRegionId)) { IDHash_add(sliceHash, seqRegionId, SliceAdaptor_fetchBySeqRegionId(sa, seqRegionId, POS_UNDEF, POS_UNDEF, STRAND_UNDEF)); } Slice *slice = IDHash_getValue(sliceHash, seqRegionId); Slice *ptSlice = slice; char *srName = Slice_getSeqRegionName(slice); CoordSystem *srCs = Slice_getCoordSystem(slice); // // remap the feature coordinates to another coord system // if a mapper was provided // if (assMapper != NULL) { MapperRangeSet *mrs; // Slightly suspicious about need for this if statement so left in perl statements for now if (destSlice != NULL && assMapper->objectType == CLASS_CHAINEDASSEMBLYMAPPER) { mrs = ChainedAssemblyMapper_map(assMapper, srName, seqRegionStart, seqRegionEnd, seqRegionStrand, srCs, 1, destSlice); } else { mrs = AssemblyMapper_fastMap(assMapper, srName, seqRegionStart, seqRegionEnd, seqRegionStrand, srCs, NULL); } // skip features that map to gaps or coord system boundaries if (MapperRangeSet_getNumRange(mrs) == 0) { continue; } MapperRange *range = MapperRangeSet_getRangeAt(mrs, 0); if (range->rangeType == MAPPERRANGE_GAP) { fprintf(stderr,"Got a mapper gap in gene obj_from_sth - not sure if this is allowed\n"); exit(1); } else { MapperCoordinate *mc = (MapperCoordinate *)range; seqRegionId = mc->id; seqRegionStart = mc->start; seqRegionEnd = mc->end; seqRegionStrand = mc->strand; } MapperRangeSet_free(mrs); if (! IDHash_contains(sliceHash, seqRegionId)) { IDHash_add(sliceHash, seqRegionId, SliceAdaptor_fetchBySeqRegionId(sa, seqRegionId, POS_UNDEF, POS_UNDEF, STRAND_UNDEF)); } ptSlice = IDHash_getValue(sliceHash, seqRegionId); } // // If a destination slice was provided convert the coords // If the dest_slice starts at 1 and is foward strand, nothing needs doing // if (destSlice != NULL) { if (destSliceStart != 1 || destSliceStrand != 1) { if (destSliceStrand == 1) { seqRegionStart = seqRegionStart - destSliceStart + 1; seqRegionEnd = seqRegionEnd - destSliceStart + 1; } else { long tmpSeqRegionStart = seqRegionStart; seqRegionStart = destSliceEnd - seqRegionEnd + 1; seqRegionEnd = destSliceEnd - tmpSeqRegionStart + 1; seqRegionStrand = -seqRegionStrand; } } // throw away features off the end of the requested slice if (seqRegionEnd < 1 || seqRegionStart > destSliceLength || (destSliceSrId != seqRegionId)) { continue; } ptSlice = destSlice; } // Finally, create the new PredictionTranscript. PredictionTranscript *pt = PredictionTranscript_new(); PredictionTranscript_setStart (pt, seqRegionStart); PredictionTranscript_setEnd (pt, seqRegionEnd); PredictionTranscript_setStrand (pt, seqRegionStrand); PredictionTranscript_setSlice (pt, ptSlice); PredictionTranscript_setAnalysis (pt, analysis); PredictionTranscript_setAdaptor (pt, (BaseAdaptor *)pta); PredictionTranscript_setDbID (pt, predictionTranscriptId); PredictionTranscript_setDisplayLabel(pt, displayLabel); Vector_addElement(pTranscripts, pt); } IDHash_free(sliceHash, NULL); return pTranscripts; }
Vector *GenomicAlignAdaptor_objectsFromStatementHandle(GenomicAlignAdaptor *gaa, StatementHandle *sth, int reverse) { Vector *results = Vector_new(); ResultRow *row; DNAFragAdaptor *dfa; IDType consensusDNAFragId; IDType queryDNAFragId; int consensusStart; int consensusEnd; int queryStart; int queryEnd; int queryStrand; IDType methodLinkId; double score; double percId; char *cigarString; dfa = ComparaDBAdaptor_getDNAFragAdaptor(gaa->dba); while ((row = sth->fetchRow(sth))) { GenomicAlign *genomicAlign; char *alignmentType; if (reverse) { queryDNAFragId = row->getLongLongAt(row,0); queryStart = row->getIntAt(row,1); queryEnd = row->getIntAt(row,2); consensusDNAFragId = row->getLongLongAt(row,3); consensusStart = row->getIntAt(row,4); consensusEnd = row->getIntAt(row,5); } else { consensusDNAFragId = row->getLongLongAt(row,0); consensusStart = row->getIntAt(row,1); consensusEnd = row->getIntAt(row,2); queryDNAFragId = row->getLongLongAt(row,3); queryStart = row->getIntAt(row,4); queryEnd = row->getIntAt(row,5); } queryStrand = row->getIntAt(row,6); methodLinkId = row->getLongLongAt(row,7); score = row->getDoubleAt(row,8); percId = row->getDoubleAt(row,9); cigarString = row->getStringAt(row,10); alignmentType = GenomicAlignAdaptor_alignmentTypeByMethodLinkId(gaa, methodLinkId); if (reverse) { StrUtil_strReplChrs(cigarString,"DI","ID"); // alignment of the opposite strand if (queryStrand == -1) { cigarString = CigarStrUtil_reverse(cigarString, strlen(cigarString)); } } genomicAlign = GenomicAlign_new(); GenomicAlign_setAdaptor(genomicAlign, (BaseAdaptor *)gaa); GenomicAlign_setConsensusDNAFrag(genomicAlign, DNAFragAdaptor_fetchByDbID(dfa,consensusDNAFragId)); GenomicAlign_setConsensusStart(genomicAlign, consensusStart); GenomicAlign_setConsensusEnd(genomicAlign, consensusEnd); GenomicAlign_setQueryDNAFrag(genomicAlign, DNAFragAdaptor_fetchByDbID(dfa,queryDNAFragId)); GenomicAlign_setQueryStart(genomicAlign, queryStart); GenomicAlign_setQueryEnd(genomicAlign, queryEnd); GenomicAlign_setQueryStrand(genomicAlign, queryStrand); GenomicAlign_setAlignmentType(genomicAlign, alignmentType); GenomicAlign_setScore(genomicAlign, score); GenomicAlign_setPercentId(genomicAlign, percId); GenomicAlign_setCigarString(genomicAlign, cigarString); Vector_addElement(results, genomicAlign); } return results; }
Vector *DBEntryAdaptor_fetchByObjectType(DBEntryAdaptor *dbea, IDType ensObj, char *ensType) { Vector *out; char qStr[1024]; StatementHandle *sth; ResultRow *row; IDHash *seen; if (!ensObj) { fprintf(stderr,"Error: Can't fetchByObjectType without an object\n"); exit(1); } if (!ensType) { fprintf(stderr,"Error: Can't fetchByObjectType without a type\n"); exit(1); } // Not sure if idt identities are right way round sprintf(qStr, "SELECT xref.xref_id, xref.dbprimary_acc, xref.display_label, xref.version," " xref.description," " exDB.db_name, exDB.db_release, exDB.status," " oxr.object_xref_id," " es.synonym," " idt.xref_identity, idt.ensembl_identity" " FROM (external_db exDB, object_xref oxr, xref xref)" " LEFT JOIN external_synonym es on es.xref_id = xref.xref_id" " LEFT JOIN identity_xref idt on idt.object_xref_id = oxr.object_xref_id" " WHERE xref.xref_id = oxr.xref_id" " AND xref.external_db_id = exDB.external_db_id" " AND oxr.ensembl_id = " IDFMTSTR " AND oxr.ensembl_object_type = '%s'", ensObj, ensType); sth = dbea->prepare((BaseAdaptor *)dbea,qStr,strlen(qStr)); sth->execute(sth); seen = IDHash_new(IDHASH_SMALL); out = Vector_new(); while ((row = sth->fetchRow(sth))) { DBEntry *exDB; IDType refID = row->getLongLongAt(row,0); // using an outer join on the synonyms as well as on identity_xref, we // now have to filter out the duplicates (see v.1.18 for // original). Since there is at most one identity_xref row per xref, // this is easy enough; all the 'extra' bits are synonyms if (!IDHash_contains(seen,refID)) { exDB = DBEntry_new(); DBEntry_setAdaptor(exDB,(BaseAdaptor *)dbea); DBEntry_setDbID(exDB, refID); DBEntry_setPrimaryId(exDB, row->getStringAt(row,1)); DBEntry_setDisplayId(exDB, row->getStringAt(row,2)); DBEntry_setVersion(exDB, row->getStringAt(row,3)); DBEntry_setDbName(exDB, row->getStringAt(row,5)); DBEntry_setRelease(exDB, row->getStringAt(row,6)); if (row->col(row,10)) { IdentityXref *idx = IdentityXref_new(); DBEntry_setIdentityXref(exDB,idx); IdentityXref_setQueryIdentity(idx, row->getDoubleAt(row,10)); IdentityXref_setTargetIdentity(idx, row->getDoubleAt(row,11)); } if (row->col(row,4)) DBEntry_setDescription(exDB, row->getStringAt(row,4)); if (row->col(row,7)) DBEntry_setStatus(exDB, row->getStringAt(row,7)); Vector_addElement(out, exDB); IDHash_add(seen, refID, exDB); } exDB = IDHash_getValue(seen, refID); if (row->col(row,9)) { DBEntry_addSynonym(exDB,row->getStringAt(row,9)); } } IDHash_free(seen, NULL); sth->finish(sth); return out; }
Vector *GenomicAlignAdaptor_mergeAlignsets(GenomicAlignAdaptor *gaa, Vector *alignSet1, Vector *alignSet2) { int i; Vector *bigList = Vector_new(); IDHash *overlappingSets[2]; Vector *mergedAligns; for (i=0;i<Vector_getNumElement(alignSet1); i++) { GenomicAlign *align = Vector_getElementAt(alignSet1, i); Vector_addElement(bigList, GenomicAlignListElem_new(DNAFrag_getDbID(GenomicAlign_getQueryDNAFrag(align)), GenomicAlign_getQueryStart(align), align, 0)); Vector_addElement(bigList, GenomicAlignListElem_new(DNAFrag_getDbID(GenomicAlign_getQueryDNAFrag(align)), GenomicAlign_getQueryEnd(align)+0.5, align, 0)); } for (i=0;i<Vector_getNumElement(alignSet2); i++) { GenomicAlign *align = Vector_getElementAt(alignSet2, i); Vector_addElement(bigList, GenomicAlignListElem_new(DNAFrag_getDbID(GenomicAlign_getConsensusDNAFrag(align)), GenomicAlign_getConsensusStart(align), align, 1)); Vector_addElement(bigList, GenomicAlignListElem_new(DNAFrag_getDbID(GenomicAlign_getConsensusDNAFrag(align)), GenomicAlign_getConsensusEnd(align)+0.5, align, 1)); } Vector_sort(bigList, GenomicAlignListElem_compFunc); // walking from start to end through sortlist and keep track of the // currently overlapping set of Alignments overlappingSets[0] = IDHash_new(IDHASH_SMALL); overlappingSets[1] = IDHash_new(IDHASH_SMALL); mergedAligns = Vector_new(); for (i=0; i<Vector_getNumElement(bigList); i++) { GenomicAlignListElem *gale = Vector_getElementAt(bigList,i); GenomicAlign *align = gale->align; IDType alignID = GenomicAlign_getDbID(align); int setNo = gale->setNum; if (IDHash_contains(overlappingSets[setNo], alignID)) { // remove from current overlapping set IDHash_remove(overlappingSets[setNo], alignID, NULL); } else { int j; void **values = IDHash_getValues(overlappingSets[1-setNo]); // insert into the set and do all the overlap business IDHash_add(overlappingSets[setNo], alignID, align); // the other set contains everything this align overlaps with for (j=0; j<IDHash_getNumValues(overlappingSets[1-setNo]); j++) { GenomicAlign *align2 = values[j]; if (setNo == 0) { GenomicAlignAdaptor_addDerivedAlignments(gaa, mergedAligns, align, align2); } else { GenomicAlignAdaptor_addDerivedAlignments(gaa, mergedAligns, align2, align); } } free(values); } } // NIY Free gale return mergedAligns; }
Vector *GenomicAlignAdaptor_fetchAllByDNAFragGenomeDB(GenomicAlignAdaptor *gaa, DNAFrag *dnaFrag, GenomeDB *targetGenome, int *startP, int *endP, char *alignmentType) { Vector *result = NULL; GenomeDB *genomeCons; IDType methodLinkId; GenomeDB *genomeQuery; Vector *mergedAligns; int ok = 1; if (!dnaFrag) { fprintf(stderr, "Error: dnaFrag argument must be non NULL\n"); ok = 0; } if (ok) { methodLinkId = GenomicAlignAdaptor_methodLinkIdByAlignmentType(gaa, alignmentType); genomeCons = DNAFrag_getGenomeDB(dnaFrag); genomeQuery = targetGenome; // direct or indirect ?? if (GenomeDB_hasConsensus(genomeCons, genomeQuery, methodLinkId) || GenomeDB_hasQuery(genomeCons, genomeQuery, methodLinkId)) { result = GenomicAlignAdaptor_fetchAllByDNAFragGenomeDBDirect(gaa, dnaFrag, targetGenome, startP, endP, methodLinkId); } else { // indirect checks Vector *linkedCons = GenomeDB_linkedGenomesByMethodLinkId(genomeCons, methodLinkId); Vector *linkedQuery = GenomeDB_linkedGenomesByMethodLinkId(genomeQuery, methodLinkId); // there are not many genomes, square effort is cheap Vector *linked = Vector_new(); Vector *set1 = Vector_new(); mergedAligns = Vector_new(); int i; for (i=0; i<Vector_getNumElement(linkedCons); i++) { int j; GenomeDB *g1 = Vector_getElementAt(linkedCons, i); for (j=0; j<Vector_getNumElement(linkedQuery); j++) { GenomeDB *g2 = Vector_getElementAt(linkedQuery, i); if (g1 == g2) { Vector_addElement(linked, g1); } } } Vector_free(linkedCons); Vector_free(linkedQuery); // collect GenomicAligns from all linked genomes for (i=0; i<Vector_getNumElement(linked); i++) { GenomeDB *g = Vector_getElementAt(linked, i); Vector *gres = GenomicAlignAdaptor_fetchAllByDNAFragGenomeDBDirect(gaa, dnaFrag, g, startP, endP, methodLinkId); Vector_append(set1, gres); Vector_free(gres); } // go from each dnafrag in the result set to target_genome // there is room for improvement here: create start end // my %frags = map { $_->query_dnafrag->dbID => $_->query_dnafrag } @$set1; for (i=0; i<Vector_getNumElement(set1); i++) { GenomicAlign *alignA = Vector_getElementAt(set1,i); DNAFrag *frag = GenomicAlign_getQueryDNAFrag(alignA); int qStart = GenomicAlign_getQueryStart(alignA); int qEnd = GenomicAlign_getQueryEnd(alignA); Vector *dres = GenomicAlignAdaptor_fetchAllByDNAFragGenomeDBDirect(gaa, frag, genomeQuery, &qStart, &qEnd, methodLinkId); int j; for (j=0; j<Vector_getNumElement(dres); j++) { GenomicAlign *alignB = Vector_getElementAt(dres,j); GenomicAlignAdaptor_addDerivedAlignments(gaa, mergedAligns, alignA, alignB); } Vector_free(dres); } // NIY freeing result = mergedAligns; } } return result; }
Vector *GenomicAlignAdaptor_fetchAllByDNAFragGenomeDBDirect( GenomicAlignAdaptor *gaa, DNAFrag *dnaFrag, GenomeDB *targetGenome, int *startP, int *endP, IDType methodLinkId) { IDType dnaFragId; GenomeDB *genomeDB; char *qStr = NULL; char tmpStr[512]; Vector *results; StatementHandle *sth; int ok = 0; if (!dnaFrag) { fprintf(stderr, "Error: Input dnafrag must not be NULL\n"); ok = 0; } if (ok) { // formatting the dnafrag dnaFragId = DNAFrag_getDbID(dnaFrag); genomeDB = DNAFrag_getGenomeDB(dnaFrag); StrUtil_copyString(&qStr, "SELECT gab.consensus_dnafrag_id," " gab.consensus_start," " gab.consensus_end," " gab.query_dnafrag_id," " gab.query_start," " gab.query_end," " gab.query_strand," " gab.method_link_id," " gab.score," " gab.perc_id," " gab.cigar_line" " FROM genomic_align_block gab ",0); if (targetGenome) { qStr = StrUtil_appendString(qStr,", dnafrag d"); } sprintf(tmpStr," WHERE gab.method_link_id = " IDFMTSTR, methodLinkId); qStr = StrUtil_appendString(qStr,tmpStr); results = Vector_new(); if (!targetGenome || GenomeDB_hasQuery(genomeDB, targetGenome, methodLinkId)) { Vector *qres; sprintf(tmpStr," AND gab.consensus_dnafrag_id = " IDFMTSTR, dnaFragId); qStr = StrUtil_appendString(qStr, tmpStr); if (startP && endP) { int lowerBound = *startP - gaa->maxAlignmentLength; sprintf(tmpStr, " AND gab.consensus_start <= %d" " AND gab.consensus_start >= %d" " AND gab.consensus_end >= %d", *endP, lowerBound, *startP ) ; qStr = StrUtil_appendString(qStr, tmpStr); } if (targetGenome) { sprintf(tmpStr, " AND gab.query_dnafrag_id = d.dnafrag_id" " AND d.genome_db_id = " IDFMTSTR, GenomeDB_getDbID(targetGenome)); qStr = StrUtil_appendString(qStr, tmpStr); } sth = gaa->prepare((BaseAdaptor *)gaa, qStr, strlen(qStr)); sth->execute(sth); qres = GenomicAlignAdaptor_objectsFromStatementHandle(gaa, sth, 0); Vector_append(results,qres); Vector_free(qres); sth->finish(sth); } if (!targetGenome || GenomeDB_hasConsensus(genomeDB, targetGenome, methodLinkId)) { Vector *cres; sprintf(tmpStr," AND gab.query_dnafrag_id = " IDFMTSTR, dnaFragId); qStr = StrUtil_appendString(qStr, tmpStr); if (startP && endP) { int lowerBound = *startP - gaa->maxAlignmentLength; sprintf(tmpStr, " AND gab.query_start <= %d" " AND gab.query_start >= %d" " AND gab.query_end >= %d", *endP, lowerBound, *startP ) ; qStr = StrUtil_appendString(qStr, tmpStr); } if (targetGenome) { sprintf(tmpStr, " AND gab.consensus_dnafrag_id = d.dnafrag_id" " AND d.genome_db_id = " IDFMTSTR, GenomeDB_getDbID(targetGenome)); qStr = StrUtil_appendString(qStr, tmpStr); } sth = gaa->prepare((BaseAdaptor *)gaa, qStr, strlen(qStr)); sth->execute(sth); cres = GenomicAlignAdaptor_objectsFromStatementHandle(gaa, sth, 1); Vector_append(results,cres); Vector_free(cres); sth->finish(sth); } } if (qStr) free(qStr); return results; }
Vector* Vector_copy(const Vector* vec) { return Vector_new(ArgList_copy(vec->vals)); }
static void testPool(const char *testURL) { URL_T url; char *schema; ConnectionPool_T pool; char *data[]= {"Fry", "Leela", "Bender", "Farnsworth", "Zoidberg", "Amy", "Hermes", "Nibbler", "Cubert", "Zapp", "Joey Mousepad", "ЯΣ༆", 0}; if (Str_startsWith(testURL, "mysql")) { schema = SCHEMA_MYSQL; } else if (Str_startsWith(testURL, "postgresql")) { schema = SCHEMA_POSTGRESQL; } else if (Str_startsWith(testURL, "sqlite")) { schema = SCHEMA_SQLITE; } else if (Str_startsWith(testURL, "oracle")) { schema = SCHEMA_ORACLE; } else { printf("Unsupported database protocol\n"); exit(1); } printf("=> Test1: create/destroy\n"); { pool = ConnectionPool_new(URL_new(testURL)); assert(pool); url = ConnectionPool_getURL(pool); ConnectionPool_free(&pool); assert(! pool); URL_free(&url); } printf("=> Test1: OK\n\n"); printf("=> Test2: NULL value\n"); { url = URL_new(NULL); assert(! url); pool = ConnectionPool_new(url); assert(! pool); } printf("=> Test2: OK\n\n"); printf("=> Test3: start/stop\n"); { url = URL_new(testURL); pool = ConnectionPool_new(url); assert(pool); ConnectionPool_start(pool); ConnectionPool_stop(pool); ConnectionPool_free(&pool); assert(pool==NULL); URL_free(&url); // Test that exception is thrown on start error TRY { url = URL_new("not://a/database"); pool = ConnectionPool_new(url); assert(pool); ConnectionPool_start(pool); printf("\tResult: Test failed -- exception not thrown\n"); exit(1); } CATCH(SQLException) { // OK } FINALLY { ConnectionPool_free(&pool); assert(pool==NULL); URL_free(&url); } END_TRY; } printf("=> Test3: OK\n\n"); printf("=> Test4: Connection execute & transaction\n"); { int i; Connection_T con; url = URL_new(testURL); pool = ConnectionPool_new(url); assert(pool); ConnectionPool_setAbortHandler(pool, TabortHandler); ConnectionPool_start(pool); con = ConnectionPool_getConnection(pool); assert(con); TRY Connection_execute(con, "drop table zild_t;"); ELSE END_TRY; Connection_execute(con, "%s", schema); Connection_beginTransaction(con); /* Insert values into database and assume that auto increment of id works */ for (i = 0; data[i]; i++) Connection_execute(con, "insert into zild_t (name, percent) values('%s', %d.%d);", data[i], i+1, i); // Assert that the last insert statement added one row assert(Connection_rowsChanged(con) == 1); /* Assert that last row id works for MySQL and SQLite. Neither Oracle nor PostgreSQL support last row id directly. The way to do this in PostgreSQL is to use currval() or return the id on insert. */ if (IS(URL_getProtocol(url), "sqlite") || IS(URL_getProtocol(url), "mysql")) assert(Connection_lastRowId(con) == 12); Connection_commit(con); printf("\tResult: table zild_t successfully created\n"); Connection_close(con); } printf("=> Test4: OK\n\n"); printf("=> Test5: Prepared Statement\n"); { int i; char blob[8192]; char *images[]= {"Ceci n'est pas une pipe", "Mona Lisa", "Bryllup i Hardanger", "The Scream", "Vampyre", "Balcony", "Cycle", "Day & Night", "Hand with Reflecting Sphere", "Drawing Hands", "Ascending and Descending", 0}; Connection_T con = ConnectionPool_getConnection(pool); assert(con); // 1. Prepared statement, perform a nonsense update to test rowsChanged PreparedStatement_T p1 = Connection_prepareStatement(con, "update zild_t set image=?;"); PreparedStatement_setString(p1, 1, ""); PreparedStatement_execute(p1); printf("\tRows changed: %lld\n", PreparedStatement_rowsChanged(p1)); // Assert that all 12 rows in the data set was changed assert(PreparedStatement_rowsChanged(p1) == 12); // 2. Prepared statement, update the table proper with "images". PreparedStatement_T pre = Connection_prepareStatement(con, "update zild_t set image=? where id=?;"); assert(pre); for (i = 0; images[i]; i++) { PreparedStatement_setBlob(pre, 1, images[i], (int)strlen(images[i])+1); PreparedStatement_setInt(pre, 2, i + 1); PreparedStatement_execute(pre); } // The last execute changed one row only assert(PreparedStatement_rowsChanged(pre) == 1); /* Add a database null blob value */ PreparedStatement_setBlob(pre, 1, NULL, 0); PreparedStatement_setInt(pre, 2, 5); PreparedStatement_execute(pre); /* Add a database null string value */ PreparedStatement_setString(pre, 1, NULL); PreparedStatement_setInt(pre, 2, 1); PreparedStatement_execute(pre); /* Add a large blob */ memset(blob, 'x', 8192); blob[8191] = 0; /* Mark start and end */ *blob='S'; blob[8190] = 'E'; PreparedStatement_setBlob(pre, 1, blob, 8192); PreparedStatement_setInt(pre, 2, i + 1); PreparedStatement_execute(pre); printf("\tResult: prepared statement successfully executed\n"); Connection_close(con); } printf("=> Test5: OK\n\n"); printf("=> Test6: Result Sets\n"); { int i; int imagesize = 0; Connection_T con; ResultSet_T rset; ResultSet_T names; PreparedStatement_T pre; con = ConnectionPool_getConnection(pool); assert(con); rset = Connection_executeQuery(con, "select id, name, percent, image from zild_t where id < %d order by id;", 100); assert(rset); printf("\tResult:\n"); printf("\tNumber of columns in resultset: %d\n\t", ResultSet_getColumnCount(rset)); assert(4==ResultSet_getColumnCount(rset)); i = 1; printf("%-5s", ResultSet_getColumnName(rset, i++)); printf("%-16s", ResultSet_getColumnName(rset, i++)); printf("%-10s", ResultSet_getColumnName(rset, i++)); printf("%-16s", ResultSet_getColumnName(rset, i++)); printf("\n\t------------------------------------------------------\n"); while (ResultSet_next(rset)) { int id = ResultSet_getIntByName(rset, "id"); const char *name = ResultSet_getString(rset, 2); double percent = ResultSet_getDoubleByName(rset, "percent"); const char *blob = (char*)ResultSet_getBlob(rset, 4, &imagesize); printf("\t%-5d%-16s%-10.2f%-16.38s\n", id, name ? name : "null", percent, imagesize ? blob : ""); } rset = Connection_executeQuery(con, "select image from zild_t where id=12;"); assert(1==ResultSet_getColumnCount(rset)); // Assert that types are interchangeable (to some degree) and that all data is returned while (ResultSet_next(rset)) { const char *image = ResultSet_getStringByName(rset, "image"); const void *blob = ResultSet_getBlobByName(rset, "image", &imagesize); assert(image && blob); assert(strlen(image) + 1 == 8192); assert(imagesize == 8192); } printf("\tResult: check max rows.."); Connection_setMaxRows(con, 3); rset = Connection_executeQuery(con, "select id from zild_t;"); assert(rset); i = 0; while (ResultSet_next(rset)) i++; assert((i)==3); printf("success\n"); printf("\tResult: check prepared statement resultset.."); Connection_setMaxRows(con, 0); pre = Connection_prepareStatement(con, "select name from zild_t where id=?"); assert(pre); PreparedStatement_setInt(pre, 1, 2); names = PreparedStatement_executeQuery(pre); assert(names); assert(ResultSet_next(names)); assert(Str_isEqual("Leela", ResultSet_getString(names, 1))); printf("success\n"); printf("\tResult: check prepared statement re-execute.."); PreparedStatement_setInt(pre, 1, 1); names = PreparedStatement_executeQuery(pre); assert(names); assert(ResultSet_next(names)); assert(Str_isEqual("Fry", ResultSet_getString(names, 1))); printf("success\n"); printf("\tResult: check prepared statement without in-params.."); pre = Connection_prepareStatement(con, "select name from zild_t;"); assert(pre); names = PreparedStatement_executeQuery(pre); assert(names); for (i = 0; ResultSet_next(names); i++); assert(i==12); printf("success\n"); /* Need to close and release statements before we can drop the table, sqlite need this */ Connection_clear(con); Connection_execute(con, "drop table zild_t;"); Connection_close(con); ConnectionPool_stop(pool); ConnectionPool_free(&pool); assert(pool==NULL); URL_free(&url); } printf("=> Test6: OK\n\n"); printf("=> Test7: reaper start/stop\n"); { int i; Vector_T v = Vector_new(20); url = URL_new(testURL); pool = ConnectionPool_new(url); assert(pool); ConnectionPool_setInitialConnections(pool, 4); ConnectionPool_setMaxConnections(pool, 20); ConnectionPool_setConnectionTimeout(pool, 4); ConnectionPool_setReaper(pool, 4); ConnectionPool_setAbortHandler(pool, TabortHandler); ConnectionPool_start(pool); assert(4==ConnectionPool_size(pool)); printf("Creating 20 Connections.."); for (i = 0; i<20; i++) Vector_push(v, ConnectionPool_getConnection(pool)); assert(ConnectionPool_size(pool) == 20); assert(ConnectionPool_active(pool) == 20); printf("success\n"); printf("Closing Connections down to initial.."); while (! Vector_isEmpty(v)) Connection_close(Vector_pop(v)); assert(ConnectionPool_active(pool) == 0); assert(ConnectionPool_size(pool) == 20); printf("success\n"); printf("Please wait 10 sec for reaper to harvest closed connections.."); Connection_T con = ConnectionPool_getConnection(pool); // Activate one connection to verify the reaper does not close any active fflush(stdout); sleep(10); assert(5 == ConnectionPool_size(pool)); // 4 initial connections + the one active we got above assert(1 == ConnectionPool_active(pool)); printf("success\n"); Connection_close(con); ConnectionPool_stop(pool); ConnectionPool_free(&pool); Vector_free(&v); assert(pool==NULL); URL_free(&url); } printf("=> Test7: OK\n\n"); printf("=> Test8: Exceptions handling\n"); { int i; Connection_T con; ResultSet_T result; url = URL_new(testURL); pool = ConnectionPool_new(url); assert(pool); ConnectionPool_setAbortHandler(pool, TabortHandler); ConnectionPool_start(pool); con = ConnectionPool_getConnection(pool); assert(con); /* * The following should work without throwing exceptions */ TRY { Connection_execute(con, "%s", schema); } ELSE { printf("\tResult: Creating table zild_t failed -- %s\n", Exception_frame.message); assert(false); // Should not fail } END_TRY; TRY { Connection_beginTransaction(con); for (i = 0; data[i]; i++) Connection_execute(con, "insert into zild_t (name, percent) values('%s', %d.%d);", data[i], i+1, i); Connection_commit(con); printf("\tResult: table zild_t successfully created\n"); } ELSE { printf("\tResult: Test failed -- %s\n", Exception_frame.message); assert(false); // Should not fail } FINALLY { Connection_close(con); } END_TRY; assert((con = ConnectionPool_getConnection(pool))); TRY { int i, j; const char *bg[]= {"Starbuck", "Sharon Valerii", "Number Six", "Gaius Baltar", "William Adama", "Lee \"Apollo\" Adama", "Laura Roslin", 0}; PreparedStatement_T p = Connection_prepareStatement (con, "insert into zild_t (name) values(?);"); /* If we did not get a statement, an SQLException is thrown and we will not get here. So we can safely use the statement now. Likewise, below, we do not have to check return values from the statement since any error will throw an SQLException and transfer the control to the exception handler */ for (i = 0, j = 42; bg[i]; i++, j++) { PreparedStatement_setString(p, 1, bg[i]); PreparedStatement_execute(p); } } CATCH(SQLException) { printf("\tResult: prepare statement failed -- %s\n", Exception_frame.message); assert(false); } END_TRY; TRY { printf("\t\tBattlestar Galactica: \n"); result = Connection_executeQuery(con, "select name from zild_t where id > 12;"); while (ResultSet_next(result)) printf("\t\t%s\n", ResultSet_getString(result, 1)); } CATCH(SQLException) { printf("\tResult: resultset failed -- %s\n", Exception_frame.message); assert(false); } FINALLY { Connection_close(con); } END_TRY; /* * The following should fail and throw exceptions. The exception error * message can be obtained with Exception_frame.message, or from * Connection_getLastError(con). Exception_frame.message contains both * SQL errors or api errors such as prepared statement parameter index * out of range, while Connection_getLastError(con) only has SQL errors */ TRY { assert((con = ConnectionPool_getConnection(pool))); Connection_execute(con, "%s", schema); /* Creating the table again should fail and we should not come here */ printf("\tResult: Test failed -- exception not thrown\n"); exit(1); } CATCH(SQLException) { Connection_close(con); } END_TRY; TRY { assert((con = ConnectionPool_getConnection(pool))); printf("\tTesting: Query with errors.. "); Connection_executeQuery(con, "blablabala;"); printf("\tResult: Test failed -- exception not thrown\n"); exit(1); } CATCH(SQLException) { printf("ok\n"); Connection_close(con); } END_TRY; TRY { printf("\tTesting: Prepared statement query with errors.. "); assert((con = ConnectionPool_getConnection(pool))); PreparedStatement_T p = Connection_prepareStatement(con, "blablabala;"); ResultSet_T r = PreparedStatement_executeQuery(p); while(ResultSet_next(r)); printf("\tResult: Test failed -- exception not thrown\n"); exit(1); } CATCH(SQLException) { printf("ok\n"); Connection_close(con); } END_TRY; TRY { assert((con = ConnectionPool_getConnection(pool))); printf("\tTesting: Column index out of range.. "); result = Connection_executeQuery(con, "select id, name from zild_t;"); while (ResultSet_next(result)) { int id = ResultSet_getInt(result, 1); const char *name = ResultSet_getString(result, 2); /* So far so good, now, try access an invalid column, which should throw an SQLException */ int bogus = ResultSet_getInt(result, 3); printf("\tResult: Test failed -- exception not thrown\n"); printf("%d, %s, %d", id, name, bogus); exit(1); } } CATCH(SQLException) { printf("ok\n"); Connection_close(con); } END_TRY; TRY { assert((con = ConnectionPool_getConnection(pool))); printf("\tTesting: Invalid column name.. "); result = Connection_executeQuery(con, "select name from zild_t;"); while (ResultSet_next(result)) { const char *name = ResultSet_getStringByName(result, "nonexistingcolumnname"); printf("%s", name); printf("\tResult: Test failed -- exception not thrown\n"); exit(1); } } CATCH(SQLException) { printf("ok\n"); Connection_close(con); } END_TRY; TRY { assert((con = ConnectionPool_getConnection(pool))); PreparedStatement_T p = Connection_prepareStatement(con, "update zild_t set name = ? where id = ?;"); printf("\tTesting: Parameter index out of range.. "); PreparedStatement_setInt(p, 3, 123); printf("\tResult: Test failed -- exception not thrown\n"); exit(1); } CATCH(SQLException) { printf("ok\n"); } FINALLY { Connection_close(con); } END_TRY; assert((con = ConnectionPool_getConnection(pool))); Connection_execute(con, "drop table zild_t;"); Connection_close(con); ConnectionPool_stop(pool); ConnectionPool_free(&pool); assert(pool==NULL); URL_free(&url); } printf("=> Test8: OK\n\n"); printf("=> Test9: Ensure Capacity\n"); { /* Check that MySQL ensureCapacity works for columns that exceed the preallocated buffer and that no truncation is done */ if ( Str_startsWith(testURL, "mysql")) { int myimagesize; url = URL_new(testURL); pool = ConnectionPool_new(url); assert(pool); ConnectionPool_start(pool); Connection_T con = ConnectionPool_getConnection(pool); assert(con); Connection_execute(con, "CREATE TABLE zild_t(id INTEGER AUTO_INCREMENT PRIMARY KEY, image BLOB, string TEXT);"); PreparedStatement_T p = Connection_prepareStatement(con, "insert into zild_t (image, string) values(?, ?);"); char t[4096]; memset(t, 'x', 4096); t[4095] = 0; for (int i = 0; i < 4; i++) { PreparedStatement_setBlob(p, 1, t, (i+1)*512); // store successive larger string-blobs to trigger realloc on ResultSet_getBlobByName PreparedStatement_setString(p, 2, t); PreparedStatement_execute(p); } ResultSet_T r = Connection_executeQuery(con, "select image, string from zild_t;"); for (int i = 0; ResultSet_next(r); i++) { ResultSet_getBlobByName(r, "image", &myimagesize); const char *image = ResultSet_getStringByName(r, "image"); // Blob as image should be terminated const char *string = ResultSet_getStringByName(r, "string"); assert(myimagesize == (i+1)*512); assert(strlen(image) == ((i+1)*512)); assert(strlen(string) == 4095); } p = Connection_prepareStatement(con, "select image, string from zild_t;"); r = PreparedStatement_executeQuery(p); for (int i = 0; ResultSet_next(r); i++) { ResultSet_getBlobByName(r, "image", &myimagesize); const char *image = ResultSet_getStringByName(r, "image"); const char *string = (char*)ResultSet_getStringByName(r, "string"); assert(myimagesize == (i+1)*512); assert(strlen(image) == ((i+1)*512)); assert(strlen(string) == 4095); } Connection_execute(con, "drop table zild_t;"); Connection_close(con); ConnectionPool_stop(pool); ConnectionPool_free(&pool); URL_free(&url); } } printf("=> Test9: OK\n\n"); printf("============> Connection Pool Tests: OK\n\n"); }
Vector add(Vector a, Vector b) { return Vector_new(a.x + b.x, a.y + b.y, a.z + b.z); }
int main(int argc, char *argv[]) { DBAdaptor * dba; StatementHandle *sth; ResultRow * row; Vector * slices; int nSlices; htsFile * out; int argNum = 1; char *inFName = NULL; char *outFName = NULL; char *dbUser = "******"; char *dbPass = NULL; int dbPort = 3306; char *dbHost = "ens-staging.internal.sanger.ac.uk"; char *dbName = "homo_sapiens_core_71_37"; char *assName = "GRCh37"; char *chrName = "1"; int flags = 0; int threads = 1; initEnsC(argc, argv); while (argNum < argc) { char *arg = argv[argNum]; char *val; // Ones without a val go here if (!strcmp(arg, "-U") || !strcmp(arg,"--ucsc_naming")) { flags |= M_UCSC_NAMING; } else { // Ones with a val go in this block if (argNum == argc-1) { Bamcov_usage(); } val = argv[++argNum]; if (!strcmp(arg, "-i") || !strcmp(arg,"--in_file")) { StrUtil_copyString(&inFName,val,0); } else if (!strcmp(arg, "-o") || !strcmp(arg,"--out_file")) { StrUtil_copyString(&outFName,val,0); } else if (!strcmp(arg, "-h") || !strcmp(arg,"--host")) { StrUtil_copyString(&dbHost,val,0); } else if (!strcmp(arg, "-p") || !strcmp(arg,"--password")) { StrUtil_copyString(&dbPass,val,0); } else if (!strcmp(arg, "-P") || !strcmp(arg,"--port")) { dbPort = atoi(val); } else if (!strcmp(arg, "-n") || !strcmp(arg,"--name")) { StrUtil_copyString(&dbName,val,0); } else if (!strcmp(arg, "-u") || !strcmp(arg,"--user")) { StrUtil_copyString(&dbUser,val,0); } else if (!strcmp(arg, "-t") || !strcmp(arg,"--threads")) { threads = atoi(val); } else if (!strcmp(arg, "-a") || !strcmp(arg,"--assembly")) { StrUtil_copyString(&assName,val,0); } else if (!strcmp(arg, "-v") || !strcmp(arg,"--verbosity")) { verbosity = atoi(val); // Temporary } else if (!strcmp(arg, "-c") || !strcmp(arg,"--chromosome")) { StrUtil_copyString(&chrName,val,0); } else { fprintf(stderr,"Error in command line at %s\n\n",arg); Bamcov_usage(); } } argNum++; } if (verbosity > 0) { printf("Program for calculating read coverage in a BAM file \n" "Steve M.J. Searle. [email protected] Last update April 2013.\n"); } if (!inFName || !outFName) { Bamcov_usage(); } dba = DBAdaptor_new(dbHost,dbUser,dbPass,dbName,dbPort,NULL); //nSlices = getSlices(dba, destName); nSlices = 1; slices = Vector_new(); SliceAdaptor *sa = DBAdaptor_getSliceAdaptor(dba); Slice *slice = SliceAdaptor_fetchByRegion(sa,NULL,chrName,POS_UNDEF,POS_UNDEF,1,NULL, 0); Vector_addElement(slices,slice); if (Vector_getNumElement(slices) == 0) { fprintf(stderr, "Error: No slices.\n"); exit(1); } htsFile *in = hts_open(inFName, "rb"); if (in == 0) { fprintf(stderr, "Fail to open BAM file %s\n", inFName); return 1; } hts_set_threads(in, threads); hts_idx_t *idx; idx = bam_index_load(inFName); // load BAM index if (idx == 0) { fprintf(stderr, "BAM index file is not available.\n"); return 1; } int i; for (i=0; i<Vector_getNumElement(slices); i++) { Slice *slice = Vector_getElementAt(slices,i); if (verbosity > 0) printf("Working on '%s'\n",Slice_getName(slice)); // if (verbosity > 0) printf("Stage 1 - retrieving annotation from database\n"); // Vector *genes = getGenes(slice, flags); if (verbosity > 0) printf("Stage 1 - calculating coverage\n"); calcCoverage(inFName, slice, in, idx, flags); } hts_idx_destroy(idx); hts_close(in); if (verbosity > 0) printf("Done\n"); return 0; }
Vector mult(Vector a, double b) { return Vector_new(b*a.x, b*a.y, b*a.z); }
ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList) { ProcessList* this; this = calloc(1, sizeof(ProcessList)); this->processes = Vector_new(Class(Process), true, DEFAULT_SIZE); this->processTable = Hashtable_new(140, false); this->usersTable = usersTable; this->pidWhiteList = pidWhiteList; /* tree-view auxiliary buffers */ this->processes2 = Vector_new(Class(Process), true, DEFAULT_SIZE); FILE* file = fopen(PROCSTATFILE, "r"); if (file == NULL) { CRT_fatalError("Cannot open " PROCSTATFILE); } char buffer[256]; int cpus = -1; do { cpus++; fgets(buffer, 255, file); } while (String_startsWith(buffer, "cpu")); fclose(file); this->cpuCount = MAX(cpus - 1, 1); #ifdef HAVE_LIBHWLOC this->topologyOk = false; int topoErr = hwloc_topology_init(&this->topology); if (topoErr == 0) { topoErr = hwloc_topology_load(this->topology); } if (topoErr == 0) { this->topologyOk = true; } #endif this->cpus = calloc(cpus, sizeof(CPUData)); for (int i = 0; i < cpus; i++) { this->cpus[i].totalTime = 1; this->cpus[i].totalPeriod = 1; } this->fields = calloc(LAST_PROCESSFIELD+1, sizeof(ProcessField)); // TODO: turn 'fields' into a Vector, // (and ProcessFields into proper objects). this->flags = 0; for (int i = 0; defaultHeaders[i]; i++) { this->fields[i] = defaultHeaders[i]; this->fields[i] |= Process_fieldFlags[defaultHeaders[i]]; } this->sortKey = PERCENT_CPU; this->direction = 1; this->hideThreads = false; this->shadowOtherUsers = false; this->showThreadNames = false; this->showingThreadNames = false; this->hideKernelThreads = false; this->hideUserlandThreads = false; this->treeView = false; this->highlightBaseName = false; this->highlightMegabytes = false; this->detailedCPUTime = false; this->countCPUsFromZero = false; this->updateProcessNames = false; this->treeStr = NULL; this->following = -1; if (CRT_utf8) this->treeStr = CRT_utf8 ? ProcessList_treeStrUtf8 : ProcessList_treeStrAscii; return this; }
// Also added a flag to indicate we actually want the gaps vector returned - quite often its not used in the caller and so would leak // memory Vector *RangeRegistry_checkAndRegister(RangeRegistry *registry, IDType id, long start, long end, long rStart, long rEnd, int wantGaps) { // The following was commented out due to Ensembl Genomes requirements // for bacterial genomes. // The following was uncommented because I'm not caring about those requirements if ( start > end ) { fprintf(stderr, "start argument [%ld] must be less than (or equal to) end argument [%ld]\n", start, end); exit(1); } if ( rStart > rEnd ) { fprintf(stderr, "rStart argument [%ld] must be less than (or equal to) rEnd argument [%ld]\n", rStart, rEnd); exit(1); } if ( rStart > start ) { fprintf(stderr, "rStart argument [%ld] must be less than (or equal to) start [%ld]\n", rStart, start); exit(1); } if ( rEnd < end ) { fprintf(stderr, "rEnd argument [%ld] must be greater than (or equal to) end [%ld]\n", rEnd, end); exit(1); } IDHash *regReg = RangeRegistry_getRegistry(registry); Vector *list; if (IDHash_contains(regReg, id)) { list = IDHash_getValue(regReg, id); } else { list = Vector_new(); IDHash_add(regReg, id, list); } Vector *gapPairs = NULL; if (wantGaps) { gapPairs = Vector_new(); } int len = Vector_getNumElement(list); if (len == 0) { //this is the first request for this id, return a gap pair for the // entire range and register it as seen CoordPair *cp = CoordPair_new(rStart, rEnd); Vector_addElement(list, cp); return Vector_copy(list); } //#### // loop through the list of existing ranges recording any "gaps" where // the existing range does not cover part of the requested range // int startIdx = 0; int endIdx = Vector_getNumElement(list)-1; int midIdx; CoordPair *range; // binary search the relevant pairs // helps if the list is big while ( ( endIdx - startIdx ) > 1 ) { midIdx = ( startIdx + endIdx ) >> 1; range = Vector_getElementAt(list, midIdx); if ( CoordPair_getEnd(range) < rStart ) { startIdx = midIdx; } else { endIdx = midIdx; } } long gapStart; long gapEnd; int rIdx = -1; int rStartIdx = -1; int rEndIdx; gapStart = rStart; int i; for (i=startIdx; i < len ; i++ ) { CoordPair *pRange = Vector_getElementAt(list, i); long pStart = CoordPair_getStart(pRange); long pEnd = CoordPair_getEnd(pRange); // no work needs to be done at all if we find a range pair that // entirely overlaps the requested region if ( pStart <= start && pEnd >= end ) { return Vector_new(); // perl returns undef, but that causes me problems } // find adjacent or overlapping regions already registered if ( pEnd >= ( rStart - 1 ) && pStart <= ( rEnd + 1 ) ) { if ( rStartIdx < 0 ) { // Not yet been set rStartIdx = i; } rEndIdx = i; } if ( pStart > rStart ) { gapEnd = ( rEnd < pStart ) ? rEnd : pStart - 1; if (wantGaps) { CoordPair *cp = CoordPair_new(gapStart, gapEnd); Vector_addElement(gapPairs, cp); } } gapStart = ( rStart > pEnd ) ? rStart : pEnd + 1; if ( pEnd >= rEnd && rIdx < 0 ) { rIdx = i; break; } } // do we have to make another gap? if ( gapStart <= rEnd ) { if (wantGaps) { CoordPair *cp = CoordPair_new(gapStart, rEnd); Vector_addElement(gapPairs, cp); } } // // Merge the new range into the registered list // if (rStartIdx >= 0 ) { // rStartIdx has been set to something long newStart; long newEnd; CoordPair *rStartIdxRange = Vector_getElementAt(list, rStartIdx); CoordPair *rEndIdxRange = Vector_getElementAt(list, rEndIdx); if ( rStart < CoordPair_getStart(rStartIdxRange)) { newStart = rStart; } else { newStart = CoordPair_getStart(rStartIdxRange); } if ( rEnd > CoordPair_getEnd(rEndIdxRange)) { newEnd = rEnd; } else { newEnd = CoordPair_getEnd(rEndIdxRange); } CoordPair *cp = CoordPair_new(newStart, newEnd); // Think its <= for (i=rStartIdx; i<=rEndIdx; i++) { Vector_removeElementAt(list, rStartIdx); // Always remove from rStartIdx as array is shrinking by one each time called } Vector_insertElementAt(list, rStartIdx, cp); //splice( @$list, $rstart_idx, // $rend_idx - $rstart_idx + 1, // [ $new_start, $new_end ] ); } else if (rIdx >= 0) { CoordPair *cp = CoordPair_new(rStart, rEnd); Vector_insertElementAt(list, rIdx, cp); //splice( @$list, $r_idx, 0, [ $rstart, $rend ] ); } else { CoordPair *cp = CoordPair_new(rStart, rEnd); Vector_addElement(list, cp); } // Note if wantGaps is not set then gapPairs will be NULL - but you said you didn't want it so that should be OK return gapPairs; }
void OpenFilesScreen_run(OpenFilesScreen* htop_this) { Panel* panel = htop_this->display; Panel_setHeader(panel, " FD TYPE DEVICE SIZE NODE NAME"); FunctionBar* bar = FunctionBar_new(ofsFunctions, ofsKeys, ofsEvents); IncSet* inc = IncSet_new(bar); Vector* lines = Vector_new(panel->items->type, true, DEFAULT_SIZE); OpenFilesScreen_scan(htop_this, lines, inc); OpenFilesScreen_draw(htop_this, inc); bool looping = true; while (looping) { Panel_draw(panel, true); if (inc->active) move(LINES-1, CRT_cursorX); int ch = getch(); if (ch == KEY_MOUSE) { MEVENT mevent; int ok = getmouse(&mevent); if (ok == OK) if (mevent.y >= panel->y && mevent.y < LINES - 1) { Panel_setSelected(panel, mevent.y - panel->y + panel->scrollV); ch = 0; } if (mevent.y == LINES - 1) ch = FunctionBar_synthesizeEvent(inc->bar, mevent.x); } if (inc->active) { IncSet_handleKey(inc, ch, panel, IncSet_getListItemValue, lines); continue; } switch(ch) { case ERR: continue; case KEY_F(3): case '/': IncSet_activate(inc, INC_SEARCH); break; case KEY_F(4): case '\\': IncSet_activate(inc, INC_FILTER); break; case KEY_F(5): clear(); OpenFilesScreen_scan(htop_this, lines, inc); OpenFilesScreen_draw(htop_this, inc); break; case '\014': // Ctrl+L clear(); OpenFilesScreen_draw(htop_this, inc); break; case 'q': case 27: case KEY_F(10): looping = false; break; case KEY_RESIZE: Panel_resize(panel, COLS, LINES-2); OpenFilesScreen_draw(htop_this, inc); break; default: Panel_onKey(panel, ch); } } Vector_delete(lines); FunctionBar_delete((Object*)bar); IncSet_delete(inc); }
StringBuilder_pointer StringBuilder_createEmpty() { StringBuilder_pointer result = StringBuilder_allocate(); result->vector = Vector_new(sizeof(char), VECTOR_DEFAULT); return result; }
static Value* eval_cross(Context* ctx, ArgList* arglist) { if(arglist->count != 2) { /* Two vectors are required for a cross product */ return ValErr(builtinArgs("cross", 2, arglist->count)); } Value* vector1 = Value_eval(arglist->args[0], ctx); if(vector1->type == VAL_ERR) { return vector1; } Value* vector2 = Value_eval(arglist->args[1], ctx); if(vector2->type == VAL_ERR) { Value_free(vector1); return vector2; } if(vector1->type != VAL_VEC || vector2->type != VAL_VEC) { /* Both values must be vectors */ return ValErr(typeError("Builtin dot expects two vectors.")); } if(vector1->vec->vals->count != 3) { /* Vectors must each have a size of 3 */ return ValErr(mathError("Vectors must each have a size of 3 for cross product.")); } /* First cross multiplication */ BinOp* i_pos_op = BinOp_new(BIN_MUL, Value_copy(vector1->vec->vals->args[1]), Value_copy(vector2->vec->vals->args[2])); BinOp* i_neg_op = BinOp_new(BIN_MUL, Value_copy(vector1->vec->vals->args[2]), Value_copy(vector2->vec->vals->args[1])); /* Evaluate multiplications */ Value* i_pos = BinOp_eval(i_pos_op, ctx); Value* i_neg = BinOp_eval(i_neg_op, ctx); BinOp_free(i_pos_op); BinOp_free(i_neg_op); /* Error checking */ if(i_pos->type == VAL_ERR) { Value_free(vector1); Value_free(vector2); Value_free(i_neg); return i_pos; } if(i_neg->type == VAL_ERR) { Value_free(vector1); Value_free(vector2); Value_free(i_pos); return i_neg; } /* Subtract products */ BinOp* i_op = BinOp_new(BIN_SUB, i_pos, i_neg); Value* i_val = BinOp_eval(i_op, ctx); BinOp_free(i_op); if(i_val->type == VAL_ERR) { Value_free(vector1); Value_free(vector2); return i_val; } /* Part 2 */ BinOp* j_pos_op = BinOp_new(BIN_MUL, Value_copy(vector1->vec->vals->args[0]), Value_copy(vector2->vec->vals->args[2])); BinOp* j_neg_op = BinOp_new(BIN_MUL, Value_copy(vector1->vec->vals->args[2]), Value_copy(vector2->vec->vals->args[0])); Value* j_pos = BinOp_eval(j_pos_op, ctx); Value* j_neg = BinOp_eval(j_neg_op, ctx); BinOp_free(j_pos_op); BinOp_free(j_neg_op); if(j_pos->type == VAL_ERR) { Value_free(vector1); Value_free(vector2); Value_free(j_neg); return j_pos; } if(j_neg->type == VAL_ERR) { Value_free(vector1); Value_free(vector2); Value_free(j_pos); return j_neg; } BinOp* j_op = BinOp_new(BIN_SUB, j_pos, j_neg); Value* j_val = BinOp_eval(j_op, ctx); BinOp_free(j_op); if(j_val->type == VAL_ERR) { Value_free(vector1); Value_free(vector2); return j_val; } /* Part 3 */ BinOp* k_pos_op = BinOp_new(BIN_MUL, Value_copy(vector1->vec->vals->args[0]), Value_copy(vector2->vec->vals->args[1])); BinOp* k_neg_op = BinOp_new(BIN_MUL, Value_copy(vector1->vec->vals->args[1]), Value_copy(vector2->vec->vals->args[0])); Value* k_pos = BinOp_eval(k_pos_op, ctx); Value* k_neg = BinOp_eval(k_neg_op, ctx); BinOp_free(k_pos_op); BinOp_free(k_neg_op); if(k_pos->type == VAL_ERR) { Value_free(vector1); Value_free(vector2); Value_free(k_neg); return k_pos; } if(k_neg->type == VAL_ERR) { Value_free(vector1); Value_free(vector2); Value_free(k_pos); return k_neg; } BinOp* k_op = BinOp_new(BIN_SUB, k_pos, k_neg); Value* k_val = BinOp_eval(k_op, ctx); BinOp_free(k_op); if(k_val->type == VAL_ERR) { Value_free(vector1); Value_free(vector2); return k_val; } ArgList* args = ArgList_create(3, i_val, j_val, k_val); return ValVec(Vector_new(args)); }
Vector *IntronSupportingEvidenceAdaptor_objectsFromStatementHandle(IntronSupportingEvidenceAdaptor *isea, StatementHandle *sth, AssemblyMapper *assMapper, Slice *destSlice) { SliceAdaptor *sa = DBAdaptor_getSliceAdaptor(isea->dba); AnalysisAdaptor *aa = DBAdaptor_getAnalysisAdaptor(isea->dba); Vector *features = Vector_new(); IDHash *sliceHash = IDHash_new(IDHASH_SMALL); /* Unneccesary my %analysis_hash; my %sr_name_hash; my %sr_cs_hash; */ /* Unused my $asm_cs; my $cmp_cs; my $asm_cs_vers; my $asm_cs_name; my $cmp_cs_vers; my $cmp_cs_name; if($mapper) { $asm_cs = $mapper->assembled_CoordSystem(); $cmp_cs = $mapper->component_CoordSystem(); $asm_cs_name = $asm_cs->name(); $asm_cs_vers = $asm_cs->version(); $cmp_cs_name = $cmp_cs->name(); $cmp_cs_vers = $cmp_cs->version(); } */ long destSliceStart; long destSliceEnd; int destSliceStrand; long destSliceLength; //CoordSystem *destSliceCs; char * destSliceSrName; IDType destSliceSrId = 0; //AssemblyMapperAdaptor *asma; if (destSlice) { destSliceStart = Slice_getStart(destSlice); destSliceEnd = Slice_getEnd(destSlice); destSliceStrand = Slice_getStrand(destSlice); destSliceLength = Slice_getLength(destSlice); //??destSliceCs = Slice_getCoordSystem(destSlice); destSliceSrName = Slice_getSeqRegionName(destSlice); destSliceSrId = Slice_getSeqRegionId(destSlice); //??asma = DBAdaptor_getAssemblyMapperAdaptor(ea->dba); } ResultRow *row; while ((row = sth->fetchRow(sth))) { IDType id = row->getLongLongAt(row,0); IDType analysisId = row->getLongLongAt(row,1); IDType seqRegionId = row->getLongLongAt(row,2); long seqRegionStart = row->getLongAt(row,3); long seqRegionEnd = row->getLongAt(row,4); int seqRegionStrand = row->getIntAt(row,5); char *hitName = row->getStringAt(row,6); double score = row->getDoubleAt(row,7); char *scoreType = row->getStringAt(row,8); int spliceCanonical = row->getIntAt(row,9); // get the analysis object Analysis *analysis = AnalysisAdaptor_fetchByDbID(aa, analysisId); /* // need to get the internal_seq_region, if present $seq_region_id = $self->get_seq_region_id_internal($seq_region_id); #get the slice object my $slice = $slice_hash{"ID:".$seq_region_id}; if(!$slice) { $slice = $sa->fetch_by_seq_region_id($seq_region_id); $slice_hash{"ID:".$seq_region_id} = $slice; $sr_name_hash{$seq_region_id} = $slice->seq_region_name(); $sr_cs_hash{$seq_region_id} = $slice->coord_system(); } my $sr_name = $sr_name_hash{$seq_region_id}; my $sr_cs = $sr_cs_hash{$seq_region_id}; */ if (! IDHash_contains(sliceHash, seqRegionId)) { IDHash_add(sliceHash, seqRegionId, SliceAdaptor_fetchBySeqRegionId(sa, seqRegionId, POS_UNDEF, POS_UNDEF, STRAND_UNDEF)); } Slice *slice = IDHash_getValue(sliceHash, seqRegionId); Slice *iseSlice = slice; char *srName = Slice_getSeqRegionName(slice); CoordSystem *srCs = Slice_getCoordSystem(slice); // // remap the feature coordinates to another coord system // if a mapper was provided // if (assMapper != NULL) { MapperRangeSet *mrs; // Slightly suspicious about need for this if statement so left in perl statements for now if (destSlice != NULL && assMapper->objectType == CLASS_CHAINEDASSEMBLYMAPPER) { mrs = ChainedAssemblyMapper_map(assMapper, srName, seqRegionStart, seqRegionEnd, seqRegionStrand, srCs, 1, destSlice); } else { mrs = AssemblyMapper_fastMap(assMapper, srName, seqRegionStart, seqRegionEnd, seqRegionStrand, srCs, NULL); } // skip features that map to gaps or coord system boundaries //next FEATURE if (!defined($seq_region_id)); if (MapperRangeSet_getNumRange(mrs) == 0) { continue; } MapperRange *range = MapperRangeSet_getRangeAt(mrs, 0); if (range->rangeType == MAPPERRANGE_GAP) { fprintf(stderr,"Got a mapper gap in gene obj_from_sth - not sure if this is allowed\n"); exit(1); } else { MapperCoordinate *mc = (MapperCoordinate *)range; seqRegionId = mc->id; seqRegionStart = mc->start; seqRegionEnd = mc->end; seqRegionStrand = mc->strand; } MapperRangeSet_free(mrs); /* Was - but identical if and else so why test??? #get a slice in the coord system we just mapped to if($asm_cs == $sr_cs || ($cmp_cs != $sr_cs && $asm_cs->equals($sr_cs))) { $slice = $slice_hash{"ID:".$seq_region_id} ||= $sa->fetch_by_seq_region_id($seq_region_id); } else { $slice = $slice_hash{"ID:".$seq_region_id} ||= $sa->fetch_by_seq_region_id($seq_region_id); } */ // Instead... if (! IDHash_contains(sliceHash, seqRegionId)) { IDHash_add(sliceHash, seqRegionId, SliceAdaptor_fetchBySeqRegionId(sa, seqRegionId, POS_UNDEF, POS_UNDEF, STRAND_UNDEF)); } iseSlice = IDHash_getValue(sliceHash, seqRegionId); } // // If a destination slice was provided convert the coords // If the dest_slice starts at 1 and is foward strand, nothing needs doing // if (destSlice != NULL) { if (destSliceStart != 1 || destSliceStrand != 1) { if (destSliceStrand == 1) { seqRegionStart = seqRegionStart - destSliceStart + 1; seqRegionEnd = seqRegionEnd - destSliceStart + 1; } else { long tmpSeqRegionStart = seqRegionStart; seqRegionStart = destSliceEnd - seqRegionEnd + 1; seqRegionEnd = destSliceEnd - tmpSeqRegionStart + 1; seqRegionStrand = -seqRegionStrand; } } // throw away features off the end of the requested slice if (seqRegionEnd < 1 || seqRegionStart > destSliceLength || (destSliceSrId != seqRegionId)) { continue; } iseSlice = destSlice; } IntronSupportingEvidence *ise = IntronSupportingEvidence_new(); IntronSupportingEvidence_setStart (ise, seqRegionStart); IntronSupportingEvidence_setEnd (ise, seqRegionEnd); IntronSupportingEvidence_setStrand (ise, seqRegionStrand); IntronSupportingEvidence_setSlice (ise, iseSlice); IntronSupportingEvidence_setAnalysis (ise, analysis); IntronSupportingEvidence_setAdaptor (ise, (BaseAdaptor *)isea); IntronSupportingEvidence_setDbID (ise, id); IntronSupportingEvidence_setHitName (ise, hitName); IntronSupportingEvidence_setScore (ise, score); IntronSupportingEvidence_setScoreType (ise, scoreType); IntronSupportingEvidence_setIsSpliceCanonical(ise, spliceCanonical); Vector_addElement(features, ise); } return features; }
// For ordered, the default should be 0 (if you just need to fill out the args) // Note ONLY stable_id can be char, all other pk's must be IDType (see code) Vector *BaseAdaptor_listDbIDs(BaseAdaptor *ba, char *table, char *pk, int ordered) { int ok = 1; char colName[1024]; if (pk == NULL) { sprintf(colName, "%s_id", table); } else { strcpy(colName, pk); } char qStr[1024]; sprintf(qStr,"SELECT `%s` FROM `%s`", colName, table ); if ( BaseAdaptor_isMultiSpecies(BaseAdaptor *ba) // For now just the multi species because I don't have adaptors in the Class hierarchy // && $self->isa('Bio::EnsEMBL::DBSQL::BaseFeatureAdaptor') // && !$self->isa('Bio::EnsEMBL::DBSQL::UnmappedObjectAdaptor') ) { char tmpStr[1024]; sprintf(tmpStr, "JOIN seq_region USING (seq_region_id) " "JOIN coord_system cs USING (coord_system_id) " "WHERE cs.species_id = "IDFMTSTR, BaseAdaptor_getSpeciesId(ba)); sprintf(qStr, "%s %s", qStr, tmpStr); } if (ordered) { sprintf(qStr, "%s ORDER BY seq_region_id, seq_region_start", qStr); } StatementHandle *sth = ba->prepare(ba,qStr,strlen(qStr)); sth->execute(sth); Vector *out = Vector_new(); if (strcmp(pk, "stable_id")) { ResultRow *row; while ((row = sth->fetchRow(sth))) { char *stableId = row->getStringCopyAt(row, 0); Vector_addElement(out, stableId); } } else { IDType *idP; ResultRow *row; while ((row = sth->fetchRow(sth))) { IDType id = row->getLongLongAt(row, 0); if ((idP = calloc(1,sizeof(IDType))) == NULL) { fprintf(stderr, "Failed allocating space for a id\n"); ok = 0; } else { *idP = id; Vector_addElement(out, idP); } } } if (!ok) { Vector_free(out); out = NULL; } return out; }