Logo Search packages:      
Sourcecode: maqview version File versions  Download package

view_goto.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "maqview.h"

#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/gl.h>
#include <GL/glu.h>
#include "GL/glut.h"
#ifdef HAVE_FREEGLUT
#include "GL/freeglut_ext.h"
#endif
#endif

static float mv_color_bg[3] = { 0, 0, 0 },
      mv_color_A[3] = { 0.4, 0.8, 0.0 },
      mv_color_C[3] = { 0.6, 1.0, 1.0 },
      mv_color_G[3] = { 1.0, 0.6, 0.0 },
      mv_color_T[3] = { 1.0, 0.0, 0.0 },
      mv_color_N[3] = { 0.1, 0.1, 0.1 },
      mv_color_ref[3] = { 1.0, 1.0, 1.0 },
      mv_color_nav[3] = { 1.0, 1.0, 0.5 },
      mv_color_tip[3] = { 1.0, 1.0, 0.5 },
      mv_color_sel[3] = { 0.4, 0.4, 0.3 },
      mv_color_lif[3] = { 0.7, 0.0, 0.3 },
      mv_color_lib[3] = { 0.3, 0.0, 0.7 },
      mv_color_def[3] = { 1.0, 1.0, 1.0 };;

View* createView(const char *map_file, const char *cns_file, int width, int height, int style){
      MapIndex *index;
      View *view;
      char *cns_name;
      int i;
      if(style != 0){
            fprintf(stderr, "Cannot support style:%d\n", style);
            return NULL;
      }
      index = load_map_index(map_file, 0);
      if(index == NULL) return NULL;
      view = (View*)malloc(sizeof(View));
      view->map_file    = (char*)malloc(strlen(map_file) + 1);
      strcpy(view->map_file, map_file);
      view->style       = style;
      view->font        = GLUT_BITMAP_8_BY_13;
      view->big_font    = GLUT_BITMAP_9_BY_15;
      view->width       = width;
      view->height      = height;
      view->font_width  = 8;
      view->font_height = 13;
      view->font_line_height = 13;
      view->ch_width    = width / view->font_width;

      view->mode = VIEW_MODE_CHARACTER;

      view->base_width  = 5;
      view->base_margin = 0.5;
      view->base_height = 4;
      view->base_line_height = 5;

      view->line_width  = 5;
      view->line_height = 6;

      view->scale_x = 1.0;
      view->scale_y = 1.0;

      view->nav.square_size = 10;
      view->nav.center_x    = width / 2;
      view->nav.center_y    = 4 * view->nav.square_size;
      view->nav.arrow_size  = 20;
      view->nav.arrow_x    = view->nav.center_x;
      view->nav.arrow_y    = view->nav.center_y;
      view->nav.state       = 0;

      memcpy(view->bgColor.rgb, mv_color_bg, sizeof(float) * 3);
      memcpy(view->ref_color.rgb, mv_color_ref, sizeof(float) * 3);
      memcpy(view->select_color.rgb, mv_color_sel, sizeof(float) * 3);
      memcpy(view->default_color.rgb, mv_color_def, sizeof(float) * 3);
      memcpy(view->line_forward_color.rgb, mv_color_lif, sizeof(float) * 3);
      memcpy(view->line_backward_color.rgb, mv_color_lib, sizeof(float) * 3);

      view->mismatch_color.rgb[0] = 1;
      view->mismatch_color.rgb[1] = 0;
      view->mismatch_color.rgb[2] = 0;

      memcpy(view->nav_color.rgb, mv_color_nav, sizeof(float) * 3);
      memcpy(view->tip_color.rgb, mv_color_tip, sizeof(float) * 3);

      i = 100;
      view->qual_color_table = (Color*)malloc(sizeof(Color) * (i + 1));
      while (i >= 0) {
            float value = (float)((i >= MAX_BASE_Q)? MAX_BASE_Q : i) / MAX_BASE_Q;
            value = 0.8 * value + 0.2;
            view->qual_color_table[i].rgb[0] = value;
            view->qual_color_table[i].rgb[1] = value;
            view->qual_color_table[i].rgb[2] = value;
            i --;
      }

      view->base_color_table = (Color*)malloc(sizeof(Color) * 5);
      memcpy(view->base_color_table[0].rgb, mv_color_A, sizeof(float) * 3);
      memcpy(view->base_color_table[1].rgb, mv_color_C, sizeof(float) * 3);
      memcpy(view->base_color_table[2].rgb, mv_color_G, sizeof(float) * 3);
      memcpy(view->base_color_table[3].rgb, mv_color_T, sizeof(float) * 3);
      memcpy(view->base_color_table[4].rgb, mv_color_N, sizeof(float) * 3);

      view->default_ref_char = '-';

      view->refs.cache = read_cache_init(index);

      view->refs.show_id    = 0;
      view->refs.show_start = 0;
      view->refs.tooltips     = (unsigned char*)malloc(TOOLTIP_SIZE);
      memset(view->refs.tooltips, 0, TOOLTIP_SIZE);

      cns_name = cns_file? (char*)cns_file : (char*)calloc(strlen(map_file)+6, 1);
      view->refs.cns = open_cns_cache(cns_name);
      if(view->refs.cns == NULL){
            view->refs.cns = cns_cache_init();
      } else {
            justify_cns_cache(view->refs.cns, view->refs.cache->index->mm->ref_name, view->refs.cache->index->mm->n_ref);
            for(i=0;i<view->refs.cache->index->mm->n_ref;i++){
                  view->refs.cache->ref_lengths[i] = view->refs.cns->ref_lengths[i];
                  if(view->refs.cache->index->trees[i]->right < view->refs.cns->ref_lengths[i]){
                        view->refs.cache->index->trees[i]->right = view->refs.cns->ref_lengths[i];
                  }
            }
      }
      view->cns_file = (char*)malloc(strlen(cns_name) + 1);
      strcpy(view->cns_file, cns_name);
      if(!cns_file) free(cns_name);

      view->layer_offset = 1; // Deafult move down one line

      view->last_x = view->last_y = 0;
      view->old_x  = view->old_y  = 0;
      view->state = 0;

      view->rolling = 0;

      view->selecting = 0;

      view->step = 1;

      view->observer = (Observer*)malloc(sizeof(Observer));
      view->observer->n_ob = 0;
      view->observer->objects = NULL;
      view->observer->notify  = NULL;


      return view;
}

View* view_clone(View *view){
      return createView(view->map_file, view->cns_file, view->width, view->height, view->style);
}

void observeView(View *view, void *observer, void (*notify)(void *obj, View *src, int event, int64_t last_x, int off_y)){
      if(!notify) return;
      view->observer->n_ob ++;
      view->observer->objects = (void**)realloc(view->observer->objects, sizeof(void*) * view->observer->n_ob);
      view->observer->notify  = (void*)realloc(view->observer->notify, sizeof(void*) * view->observer->n_ob);
      view->observer->objects[view->observer->n_ob-1] = observer;
      view->observer->notify[view->observer->n_ob-1]  = notify;
}

void removeObserverView(View * view, void *object){
      Observer *ob;
      int i;
      ob = view->observer;
      if(!ob) return;
      for(i=0;i<ob->n_ob;i++){
            if(ob->objects[i] == object){
                  ob->n_ob --;
                  if(ob->n_ob && i < ob->n_ob){
                        memmove(ob->objects + i, ob->objects + i + 1, ob->n_ob - i);
                        memmove(ob->notify + i, ob->notify + i + 1, ob->n_ob - i);
                  }
                  i --;
            }
      }
}

void notifyView(View *view, int evt, int64_t x, int y){
      int i;
      for(i=0;i<view->observer->n_ob;i++){
            view->observer->notify[i](view->observer->objects[i], view, evt, x, y);
      }
}

void view_resize(View *view, int w, int h){
      switch(view->mode){
            case VIEW_MODE_CHARACTER:
                  view->ch_width = w / view->font_width;
                  break;
            case VIEW_MODE_SQUARE:
                  view->ch_width = w / (view->base_width * view->scale_x);
                  break;
            case VIEW_MODE_LINE:
                  view->ch_width = w / (view->line_width * view->scale_x);
                  break;
            default: return;
      }
      memset(view->refs.tooltips, 0, TOOLTIP_SIZE);
      view->nav.center_x    = w / 2;
      view->nav.center_y    = 4 * view->nav.square_size;
      view->nav.arrow_x    = view->nav.center_x;
      view->nav.arrow_y    = view->nav.center_y;
      notifyView(view, VIEW_EVENT_RESIZE, view->refs.show_start, 0);
      view_goto(view, view->refs.show_id, view->refs.show_start);
}

void relayout(View *view){
      int i, j, lay_size;
      int64_t *layers;
      Read *read;
      lay_size = 256;
      layers = (int64_t*)malloc(sizeof(int64_t) * lay_size);
      memset(layers, 0, sizeof(int64_t) * lay_size);
      for(i=0;i<view->refs.cache->size;i++){
            read = view->refs.cache->reads + view->refs.cache->offset + i;
            j = 0;
            REPEAT:
            for(;j<lay_size;j++){
                  if(read_pos(read->read.pos) >= layers[j]){
                        read->y = j;
                        layers[j] = read_pos(read->read.pos) + read->read.size + 1;
                        break;
                  }
            }
            if(j == lay_size){
                  lay_size += 256;
                  layers = (int64_t*)realloc(layers, sizeof(int64_t) * lay_size);
                  memset(layers + j, 0, sizeof(int64_t) * (lay_size - j));
                  goto REPEAT;
            }
      }
      free(layers);
}

int view_locate(View *view, char *ref_name, int64_t pos){
      int ref_id;
      if(ref_name == NULL) return 0;
      for(ref_id=0;ref_id<view->refs.cache->index->mm->n_ref;ref_id++){
            if(strcmp(ref_name, view->refs.cache->index->mm->ref_name[ref_id]) == 0){
                  return view_goto(view, ref_id, pos);
            }
      }
      return 0;
}

int view_goto(View *view, int ref_id, int64_t pos){
      int i;
      int64_t start, end, last_start;
      int size, ret;
      RefSeq *refs;
      refs = &(view->refs);
      size = view->ch_width;
      start = pos - MAX_READ_SIZE;
      end   = pos + size;
      last_start = view->refs.show_start;
      ret = read_cache_put(view->refs.cache, ref_id, start, end);
      if(ret < 0){
            printf("[error]: %s:%d\n", __FILE__, __LINE__);
            return 0;
      }
      refs->show_start = pos;
//    refs->show_start = (pos<0)? 0:(pos);
      switch(ret){
            case 1:
                  notifyView(view, VIEW_EVENT_GOTO, last_start, 0);
                  break;
            default:
                  notifyView(view, VIEW_EVENT_MOVE, last_start, 0);
      }
      if(ret){
            relayout(view);
      }
      if(refs->show_id != ref_id){
            memset(refs->tooltips, 0, size);
            refs->show_id = ref_id;
      } else {
            if(refs->show_start < last_start + size && refs->show_start + size > last_start){
                  if(refs->show_start < last_start){
                        for(i=size-1;i>=last_start - refs->show_start;i--){
                              refs->tooltips[i] = refs->tooltips[i+refs->show_start-last_start];
                        }
                        for(;i>=0;i--){
                              refs->tooltips[i] = 0;
                        }
                  } else {
                        for(i=0;i<size - refs->show_start + last_start;i++){
                              refs->tooltips[i] = refs->tooltips[i+refs->show_start-last_start];
                        }
                        for(;i<size;i++){
                              refs->tooltips[i] = 0;
                        }
                  }
            } else {
                  memset(refs->tooltips, 0, size);
            }
      }
      if(refs->cns->stream && ref_id >= 0 && ref_id < refs->cns->n_mm_ref && refs->cns->mm_map[ref_id] >= 0){
            cns_cache_put(refs->cns, refs->cns->mm_map[ref_id], start, end);
      } else {
            cns_cache_guess(refs->cns, refs->cache);
      }
      return 1;
}

void closeView(View *view){
      RefSeq *refs;
      notifyView(view, VIEW_EVENT_CLOSE, 0, 0);
      free(view->observer->objects);
      free(view->observer->notify);
      free(view->observer);
      free(view->qual_color_table);
      free(view->base_color_table);
      refs = &(view->refs);
      close_cns_cache(refs->cns);
      free(refs->tooltips);
      read_cache_free(refs->cache);
      free(view->map_file);
      free(view->cns_file);
      free(view);
}

#ifdef MAIN_VIEW_GOTO

void print_view(View *view){
      int i;
      RefSeq *refs;
      Read *read;
      refs = &(view->refs);
      printf("------------------------ %lld %lld ---------------------------\n", refs->cache_start, refs->cache_end);
      for(i=0;i<refs->read_size;i++){
            read = refs->reads + refs->read_offset + i;
            printf("%s\t%d\n", read->read.name, read_pos(read->read.pos) + 1);
      }
      printf("------------------------------------------------------------\n\n");
}

int main(int argc, char **argv){
      View *view;
      int i;
      if(argc < 2){
            fprintf(stderr, "Usage: %s <map file>\n", argv[0]);
            return 1;
      }
      view = createView(argv[1], 1200, 800, 0);
      if(view == NULL){
            printf("Cannot create view on file %s\n", argv[1]);
            return 1;
      }
      view_goto(view, 0, 1000);
      for(i=0;i<100;i++){
            view_goto(view, 0, view->refs.show_start + 100);
      }
      for(;i>0;i--){
            view_goto(view, 0, view->refs.show_start - 100);
      }
      closeView(view);
      return 0;
}

#endif

Generated by  Doxygen 1.6.0   Back to index