void *BkgFitWorkerCpu(void *arg)
{
  ProcessorQueue* pq = static_cast<ProcessorQueue*>(arg);
  assert(pq);

  WorkerInfoQueue* curQ = NULL;
  bool done = false;
  WorkerInfoQueueItem item;
  while (!done)
  {
    //item = TryGettingFittingJobForCpuFromQueue(pq, &curQ);
    item = pq->TryGettingFittingJob(&curQ);
    if (item.finished == true)
    {
      // we are no longer needed...go away!
      done = true;
      curQ->DecrementDone();
      continue;
    }

    int event = * ( (int *) item.private_data);

    if (event == MULTI_FLOW_REGIONAL_FIT)
    {
      DoMultiFlowRegionalFit(item);
    }
    else if (event == INITIAL_FLOW_BLOCK_ALLBEAD_FIT)
    {
      DoInitialBlockOfFlowsAllBeadFit(item);
    }
    else if (event == INITIAL_FLOW_BLOCK_REMAIN_REGIONAL_FIT)
    {
      DoInitialBlockOfFlowsRemainingRegionalFit(item);
    }
    else if (event == SINGLE_FLOW_FIT) {
      DoSingleFlowFitAndPostProcessing(item);
    }
    else if (event == POST_FIT_STEPS) {
      DoPostFitProcessing(item);
    }
    else if (event == imageInitBkgModel)
    {
      DoConstructSignalProcessingFitterAndData (item);
    }

    // indicate we finished that bit of work
    curQ->DecrementDone();
  }

  return (NULL);
}
예제 #2
0
void *FileSDatLoadWorker ( void *arg )
{
  WorkerInfoQueue *q = static_cast<WorkerInfoQueue *> ( arg );
  assert ( q );

  bool done = false;

  while ( !done )
  {
    WorkerInfoQueueItem item = q->GetItem();

    if ( item.finished == true )
    {
      // we are no longer needed...go away!
      done = true;
      q->DecrementDone();
      continue;
    }
    ClockTimer timer;
    ImageLoadWorkInfo *one_img_loader = ( ImageLoadWorkInfo * ) item.private_data;
    SynchDat &sdat = one_img_loader->sdat[one_img_loader->cur_buffer];

    //    int flow_buffer_for_flow = one_img_loader->cur_buffer;
    if ( one_img_loader->inception_state->img_control.col_flicker_correct ) {
      ComparatorNoiseCorrector cnc;
      Mask &mask = *(one_img_loader->mask);
      for (size_t rIx = 0; rIx < sdat.GetNumBin(); rIx++) {
        TraceChunk &chunk = sdat.GetChunk(rIx);
        // Copy over temp mask for normalization
        Mask m(chunk.mWidth, chunk.mHeight);
        for (size_t r = 0; r < chunk.mHeight; r++) {
          for (size_t c = 0; c < chunk.mWidth; c++) {
            m[r*chunk.mWidth+c] = mask[(r+chunk.mRowStart) * mask.W() + (c+chunk.mColStart)];
          }
        }
        cnc.CorrectComparatorNoise(&chunk.mData[0], chunk.mHeight, chunk.mWidth, chunk.mDepth, 
                                   &m, one_img_loader->inception_state->img_control.col_flicker_correct_verbose);
      } 
    }
    // @todo output trace and dc offset info
    sdat.SubDcOffset();
    SetReadCompleted(one_img_loader);
    size_t usec = timer.GetMicroSec();
    fprintf ( stdout, "FileLoadWorker: ImageProcessing time for flow %d: %0.5lf sec\n", one_img_loader->flow, usec / 1.0e6);

    q->DecrementDone();
  }

  return ( NULL );
}
예제 #3
0
void *FileLoadWorker ( void *arg )
{
  WqInfo_t *wqinfo = (WqInfo_t *)arg;
  int threadNum=wqinfo->threadNum;
  WorkerInfoQueue *q = wqinfo->wq;
  assert ( q );

  bool done = false;
  char dateStr[256];
  struct tm newtime;
  time_t ltime;
  double T1=0,T2=0,T3,T4;

  char name[20];
  sprintf(name,"FileLdWkr%d",threadNum);
  prctl(PR_SET_NAME,name,0,0,0);

  const double noiseThreshold = 0.;  // to be set by command line option
  FluidPotentialCorrector fpCorr(noiseThreshold);

  while ( !done )
  {
    WorkerInfoQueueItem item = q->GetItem();

    if ( item.finished == true )
    {
      // we are no longer needed...go away!
      done = true;
      q->DecrementDone();
      continue;
    }
    ImageLoadWorkInfo *one_img_loader = ( ImageLoadWorkInfo * ) item.private_data;

    ClockTimer timer;
    Timer tmr;
    Image *img = &one_img_loader->img[one_img_loader->cur_buffer];

    if (one_img_loader->inception_state->img_control.threaded_file_access)
    {
      tmr.restart();
      if ( !img->LoadRaw ( one_img_loader->name) )
      {
        fprintf ( stdout, "ERROR: Failed to load raw image %s\n", one_img_loader->name );
        exit ( EXIT_FAILURE );
      }

      T1=tmr.elapsed();
      tmr.restart();
      if(img->raw->imageState & IMAGESTATE_QuickPinnedPixelDetect)
        one_img_loader->pinnedInFlow->QuickUpdate ( one_img_loader->flow, img);
      else
        one_img_loader->pinnedInFlow->Update ( one_img_loader->flow, img,(ImageTransformer::gain_correction?ImageTransformer::gain_correction:0));

      T2=tmr.elapsed();
    }

    tmr.restart();


    // correct in-channel electrical cross-talk
    ImageTransformer::XTChannelCorrect ( one_img_loader->img[one_img_loader->cur_buffer].raw, one_img_loader->img[one_img_loader->cur_buffer].results_folder ); // buffer_ix

    // testing of lossy compression
    if(ImageTransformer::PCATest[0]) {
      AdvComprTest(one_img_loader->name,&one_img_loader->img[one_img_loader->cur_buffer],ImageTransformer::PCATest,false/*one_img_loader->inception_state->img_control.col_flicker_correct*/ );
    }
    // col noise correction (if done during lossy compression will already have happened.
    else if ( !(img->raw->imageState & IMAGESTATE_ComparatorCorrected) &&
              one_img_loader->inception_state->img_control.col_flicker_correct )
    {
        if( one_img_loader->inception_state->img_control.col_pair_pixel_xtalk_correct ){
            PairPixelXtalkCorrector xtalkCorrector;
            float xtalk_fraction = one_img_loader->inception_state->img_control.pair_xtalk_fraction;
            xtalkCorrector.Correct(one_img_loader->img[one_img_loader->cur_buffer].raw, xtalk_fraction);
        }
        if (one_img_loader->inception_state->img_control.corr_noise_correct){
      	  CorrNoiseCorrector rnc;
      	  rnc.CorrectCorrNoise(one_img_loader->img[one_img_loader->cur_buffer].raw,3,one_img_loader->inception_state->bfd_control.beadfindThumbnail );
        }


      if(one_img_loader->inception_state->bfd_control.beadfindThumbnail)
      {
        //ComparatorNoiseCorrector
        ComparatorNoiseCorrector cnc;
        cnc.CorrectComparatorNoiseThumbnail(one_img_loader->img[one_img_loader->cur_buffer].raw, one_img_loader->mask, one_img_loader->inception_state->loc_context.regionXSize,one_img_loader->inception_state->loc_context.regionYSize, one_img_loader->inception_state->img_control.col_flicker_correct_verbose);
      } else {
        ComparatorNoiseCorrector cnc;
        cnc.CorrectComparatorNoise(one_img_loader->img[one_img_loader->cur_buffer].raw, one_img_loader->mask, one_img_loader->inception_state->img_control.col_flicker_correct_verbose, one_img_loader->inception_state->img_control.aggressive_cnc,false,threadNum );
      }
    }
//#define DEBUG_IMAGE_CORR_ISSUES 1
#ifdef DEBUG_IMAGE_CORR_ISSUES

        char newName[1024];
        char *nptr,*ptr=one_img_loader->name;
        while((nptr = strstr(ptr,"/")))ptr=nptr+1;
        if(*ptr == '/')
        	ptr++;
        sprintf(newName,"%s_proc",one_img_loader->name);

        Acq saver;
        saver.SetData ( &one_img_loader->img[one_img_loader->cur_buffer] );
        saver.WriteVFC(newName, 0, 0, one_img_loader->img[one_img_loader->cur_buffer].raw->cols, one_img_loader->img[one_img_loader->cur_buffer].raw->rows);
#endif
    T3=tmr.elapsed();
    tmr.restart();

    // Fluid potential corrector
    const bool correctFluidPotential = one_img_loader->inception_state->img_control.fluid_potential_correct;
    const double noiseThreshold = (double) one_img_loader->inception_state->img_control.fluid_potential_threshold;
    if (correctFluidPotential){
        fpCorr.setThreshold(noiseThreshold);

                // parse rowsum file name to load
                const std::string datFileName = one_img_loader->name;
                printf("dat file name %s\n", datFileName.c_str());
                const size_t pos1 = datFileName.find_last_of('/');
                const size_t pos2 = datFileName.find_last_of('.');
                const std::string rowsumFileName = datFileName.substr(0, pos1) + "/../rowsum/" + datFileName.substr(pos1+1, pos2-pos1-1) + ".hwsum";
                // printf("rowsum file name %s pos1 %u pos2 %u\n", rowsumFileName.c_str(), (uint32_t) pos1, (uint32_t) pos2);


                // determine if the data file is thumbnail or block
        const bool isThumbnail = one_img_loader->inception_state->bfd_control.beadfindThumbnail;
        if(isThumbnail){
                fpCorr.setIsThumbnail();
        }

        // set image
        const unsigned int regionXSize = one_img_loader->inception_state->loc_context.regionXSize;
        const unsigned int regionYSize = one_img_loader->inception_state->loc_context.regionYSize;
        const char nucChar = one_img_loader->inception_state->flow_context.ReturnNucForNthFlow(one_img_loader->flow);
        fpCorr.setImage(one_img_loader->img[one_img_loader->cur_buffer].raw, one_img_loader->mask,  regionYSize, regionXSize, nucChar);
        //printf("nucChar is %c\n", nucChar);


        // load sensing electrode data
        if (isThumbnail){
                const unsigned int numRows = one_img_loader->img[one_img_loader->cur_buffer].raw->rows;
                fpCorr.loadSensingElectrodeDataThumbnail(rowsumFileName, numRows);

        } else {
                // determine startRow and endRow
                one_img_loader->img[one_img_loader->cur_buffer].SetOffsetFromChipOrigin(one_img_loader->name);
                const unsigned int startRow = one_img_loader->img[one_img_loader->cur_buffer].raw->chip_offset_y;
                const unsigned int endRow = startRow + one_img_loader->img[one_img_loader->cur_buffer].raw->rows;
       //         printf("offset x y = %d %d, start and end rows are %u,%u\n", one_img_loader->img[one_img_loader->cur_buffer].raw->chip_offset_x,one_img_loader->img[one_img_loader->cur_buffer].raw->chip_offset_y, startRow, endRow);
                fpCorr.loadSensingElectrodeData(rowsumFileName, startRow, endRow);
        }

        // correct fluid potential
         if (fpCorr.readRowSumIsSuccess()){
                 fpCorr.doCorrection();
         } else {
                 printf("fluidPotentialCorrector skipped:  Cannot find rowsum file %s \n", rowsumFileName.c_str());
         }

    }


    // dump dc offset one_img_loaderrmation before we do any normalization
    DumpDcOffset ( one_img_loader );
    int buffer_ix = one_img_loader->cur_buffer;

    // setting the mean of frames to zero will be done by the bkgmodel as soon as its loaded.

// the traces will be zero'd by the bknd model loader anyway, no need to do them here.
 //   img->SetMeanOfFramesToZero ( one_img_loader->normStart, one_img_loader->normEnd,0 );


    // calculate the smooth pH step amplitude in empty wells across the whole image
    if ( one_img_loader->doEmptyWellNormalization )
    {
      // this is redundant with what's in the EmptyTrace class, but this method of spatial normalization
      // is going to go away soon, so not worth fixing
      MaskType referenceMask = MaskReference;

      if ( one_img_loader->inception_state->bkg_control.trace_control.use_dud_and_empty_wells_as_reference )
        referenceMask = ( MaskType ) ( MaskReference | MaskDud );

      one_img_loader->img[buffer_ix].CalculateEmptyWellLocalScaleForFlow ( * ( one_img_loader->pinnedInFlow ),one_img_loader->mask,one_img_loader->flow,referenceMask,one_img_loader->smooth_span );
#if 0
      char fname[512];
      sprintf ( fname,"ewampimg_%04d.txt",one_img_loader->flow );
      FILE *ewampfile = fopen ( fname,"w" );
      for ( int row=0;row < one_img_loader->img[buffer_ix].GetRows();row++ )
      {
        int col;

        for ( col=0;col < ( one_img_loader->img[buffer_ix].GetCols()-1 ); col++ )
          fprintf ( ewampfile,"%9.5f\t",one_img_loader->img[buffer_ix].getEmptyWellAmplitude ( row,col ) );

        fprintf ( ewampfile,"%9.5f\n",one_img_loader->img[buffer_ix].getEmptyWellAmplitude ( row,col ) );
      }
      fclose ( ewampfile );
#endif
    }

    // dump pH step debug one_img_loader to file (its really fast, don't worry)
    DumpStep ( one_img_loader );
    if ( one_img_loader->doRawBkgSubtract )
    {
      one_img_loader->img[buffer_ix].SubtractLocalReferenceTrace ( one_img_loader->mask, MaskBead, MaskReference, one_img_loader->NNinnerx,
                                                                   one_img_loader->NNinnery,one_img_loader->NNouterx,one_img_loader->NNoutery, false, true, true );
      if ( one_img_loader->flow==0 ) // absolute first flow,not flow buffer
        printf ( "Notify user: NN empty subtraction in effect.  No further warnings will be given. %d \n",one_img_loader->flow );
    }
    T4=tmr.elapsed();

    //    printf ( "Allow model to go %d \n", one_img_loader->flow );

    SetReadCompleted(one_img_loader);

    size_t usec = timer.GetMicroSec();

    ltime=time(&ltime);
    localtime_r(&ltime, &newtime);
    strftime(dateStr,sizeof(dateStr),"%H:%M:%S", &newtime);

    fprintf ( stdout, "FileLoadWorker: ImageProcessing time for flow %d: %0.2lf(ld=%.2f pin=%.2f cnc=%.2f xt=%.2f sem=%.2lf cache=%.2lf) sec %s\n",
              one_img_loader->flow , usec / 1.0e6, T1, T2, T3, T4, img->SemaphoreWaitTime, img->CacheAccessTime, dateStr);
    fflush(stdout);
    fprintf(stdout, "File: %s\n", one_img_loader->name);
    fflush(stdout);
    q->DecrementDone();
  }

  return ( NULL );
}
예제 #4
0
void *FileSDatLoadWorker ( void *arg )
{
  WorkerInfoQueue *q = static_cast<WorkerInfoQueue *> ( arg );
  assert ( q );

  bool done = false;
  TraceChunkSerializer serializer;
  while ( !done )
  {
    WorkerInfoQueueItem item = q->GetItem();

    if ( item.finished == true )
    {
      // we are no longer needed...go away!
      done = true;
      q->DecrementDone();
      continue;
    }
    ClockTimer timer;
    ImageLoadWorkInfo *one_img_loader = ( ImageLoadWorkInfo * ) item.private_data;
    bool ok = serializer.Read ( one_img_loader->name, one_img_loader->sdat[one_img_loader->cur_buffer] );
    if (!ok) {
      ION_ABORT("Couldn't load file: " + ToStr(one_img_loader->name));
    }
    one_img_loader->pinnedInFlow->Update ( one_img_loader->flow, &one_img_loader->sdat[one_img_loader->cur_buffer],(ImageTransformer::gain_correction?ImageTransformer::gain_correction:0));
    //    one_img_loader->pinnedInFlow->Update ( one_img_loader->flow, &one_img_loader->sdat[one_img_loader->cur_buffer] );

    SynchDat &sdat = one_img_loader->sdat[one_img_loader->cur_buffer];
    // if ( ImageTransformer::gain_correction != NULL )
    //   ImageTransformer::GainCorrectImage ( &sdat );
    //   ImageTransformer::GainCorrectImage ( &one_img_loader->sdat[one_img_loader->cur_buffer] );

    //    int buffer_ix = one_img_loader->cur_buffer;
    if ( one_img_loader->inception_state->img_control.col_flicker_correct ) {
      ComparatorNoiseCorrector cnc;
      Mask &mask = *(one_img_loader->mask);
      for (size_t rIx = 0; rIx < sdat.GetNumBin(); rIx++) {
        TraceChunk &chunk = sdat.GetChunk(rIx);
        // Copy over temp mask for normalization
        Mask m(chunk.mWidth, chunk.mHeight);
        for (size_t r = 0; r < chunk.mHeight; r++) {
          for (size_t c = 0; c < chunk.mWidth; c++) {
            m[r*chunk.mWidth+c] = mask[(r+chunk.mRowStart) * mask.W() + (c+chunk.mColStart)];
          }
        }
        cnc.CorrectComparatorNoise(&chunk.mData[0], chunk.mHeight, chunk.mWidth, chunk.mDepth,
            &m, one_img_loader->inception_state->img_control.col_flicker_correct_verbose,
            one_img_loader->inception_state->img_control.aggressive_cnc);
      }
    }
    // @todo output trace and dc offset info
    sdat.AdjustForDrift();
    sdat.SubDcOffset();
    SetReadCompleted(one_img_loader);
    size_t usec = timer.GetMicroSec();
    fprintf ( stdout, "FileLoadWorker: ImageProcessing time for flow %d: %0.5lf sec\n", one_img_loader->flow, usec / 1.0e6);

    q->DecrementDone();
  }

  return ( NULL );
}
예제 #5
0
void *FileLoadWorker ( void *arg )
{
  WorkerInfoQueue *q = static_cast<WorkerInfoQueue *> ( arg );
  assert ( q );

  bool done = false;

  while ( !done )
  {
    WorkerInfoQueueItem item = q->GetItem();

    if ( item.finished == true )
    {
      // we are no longer needed...go away!
      done = true;
      q->DecrementDone();
      continue;
    }
    ImageLoadWorkInfo *one_img_loader = ( ImageLoadWorkInfo * ) item.private_data;

    ClockTimer timer;

    if (one_img_loader->inception_state->img_control.threaded_file_access)
        JustLoadOneImageWithPinnedUpdate(one_img_loader);

    // col noise correction
    if ( one_img_loader->inception_state->img_control.col_flicker_correct )
    {
        if(one_img_loader->inception_state->bfd_control.beadfindThumbnail)
        {
          //ComparatorNoiseCorrector
          ComparatorNoiseCorrector cnc;
          cnc.CorrectComparatorNoiseThumbnail(one_img_loader->img[one_img_loader->cur_buffer].raw, one_img_loader->mask, one_img_loader->inception_state->loc_context.regionXSize,one_img_loader->inception_state->loc_context.regionYSize, one_img_loader->inception_state->img_control.col_flicker_correct_verbose);
        } else {
            ComparatorNoiseCorrector cnc;
            cnc.CorrectComparatorNoise(one_img_loader->img[one_img_loader->cur_buffer].raw, one_img_loader->mask, one_img_loader->inception_state->img_control.col_flicker_correct_verbose);
        }
    }

    // dump dc offset one_img_loaderrmation before we do any normalization
    DumpDcOffset ( one_img_loader );
    int flow_buffer_for_flow = one_img_loader->cur_buffer;

    one_img_loader->img[flow_buffer_for_flow].SetMeanOfFramesToZero ( one_img_loader->normStart, one_img_loader->normEnd );

    // correct in-channel electrical cross-talk
    ImageTransformer::XTChannelCorrect ( one_img_loader->img[flow_buffer_for_flow].raw, one_img_loader->img[flow_buffer_for_flow].results_folder );
    // calculate the smooth pH step amplitude in empty wells across the whole image
    if ( one_img_loader->doEmptyWellNormalization )
    {
      // this is redundant with what's in the EmptyTrace class, but this method of spatial normalization
      // is going to go away soon, so not worth fixing
      MaskType referenceMask = MaskReference;

      if ( one_img_loader->inception_state->bkg_control.use_dud_and_empty_wells_as_reference )
        referenceMask = ( MaskType ) ( MaskReference | MaskDud );

      one_img_loader->img[flow_buffer_for_flow].CalculateEmptyWellLocalScaleForFlow ( * ( one_img_loader->pinnedInFlow ),one_img_loader->mask,one_img_loader->flow,referenceMask,one_img_loader->smooth_span );
#if 0
      char fname[512];
      sprintf ( fname,"ewampimg_%04d.txt",one_img_loader->flow );
      FILE *ewampfile = fopen ( fname,"w" );
      for ( int row=0;row < one_img_loader->img[flow_buffer_for_flow].GetRows();row++ )
      {
        int col;

        for ( col=0;col < ( one_img_loader->img[flow_buffer_for_flow].GetCols()-1 ); col++ )
          fprintf ( ewampfile,"%9.5f\t",one_img_loader->img[flow_buffer_for_flow].getEmptyWellAmplitude ( row,col ) );

        fprintf ( ewampfile,"%9.5f\n",one_img_loader->img[flow_buffer_for_flow].getEmptyWellAmplitude ( row,col ) );
      }
      fclose ( ewampfile );
#endif
    }

    // dump pH step debug one_img_loader to file (its really fast, don't worry)
    DumpStep ( one_img_loader );
    if ( one_img_loader->doRawBkgSubtract )
    {
      one_img_loader->img[flow_buffer_for_flow].SubtractLocalReferenceTrace ( one_img_loader->mask, MaskBead, MaskReference, one_img_loader->NNinnerx,
          one_img_loader->NNinnery,one_img_loader->NNouterx,one_img_loader->NNoutery, false, true, true );
      if ( one_img_loader->flow==0 ) // absolute first flow,not flow buffer
        printf ( "Notify user: NN empty subtraction in effect.  No further warnings will be given. %d \n",one_img_loader->flow );
    }

    printf ( "Allow model to go %d\n", one_img_loader->flow );

    SetReadCompleted(one_img_loader);

    size_t usec = timer.GetMicroSec();

    fprintf ( stdout, "FileLoadWorker: ImageProcessing time for flow %d: %0.5lf sec\n", one_img_loader->flow , usec / 1.0e6);

    q->DecrementDone();
  }

  return ( NULL );
}