void DoMultiFlowRegionalFit (WorkerInfoQueueItem &item) {
  BkgModelWorkInfo *info = (BkgModelWorkInfo *) (item.private_data);
  FlowBlockSequence::const_iterator flowBlock =
    info->inception_state->bkg_control.signal_chunks.flow_block_sequence.BlockAtFlow( info->flow );

  info->bkgObj->InitializeFlowBlock( flowBlock->size() );

  info->bkgObj->ProcessImage (info->img, info->flow, info->flow - flowBlock->begin(),
                                flowBlock->size() );
  // execute block if necessary
  if (info->bkgObj->TestAndTriggerComputation (info->last)) 
  {
    info->bkgObj->MultiFlowRegionalFitting (info->flow, info->last,
      info->flow_key, flowBlock->size(), info->table, flowBlock->begin() ); // CPU based regional fit
    if ( info->inception_state->bkg_control.signal_chunks.flow_block_sequence.
          HasFlowInFirstFlowBlock( info->flow ))
    {
      info->type = INITIAL_FLOW_BLOCK_ALLBEAD_FIT; 
      //if (info->pq->GetGpuQueue() && info->pq->performGpuMultiFlowFitting())
      //  info->pq->GetGpuQueue()->PutItem(item);
      //else
      //  info->pq->GetCpuQueue()->PutItem(item);
      info->QueueControl->AssignMultiFLowFitItemToQueue(item);
    }
    else
    {
      info->type = SINGLE_FLOW_FIT;
      //if (info->pq->GetGpuQueue() && info->pq->performGpuSingleFlowFitting())
      //  info->pq->GetGpuQueue()->PutItem(item);
      //else
      //  info->pq->GetCpuQueue()->PutItem(item);
      info->QueueControl->AssignSingleFLowFitItemToQueue(item);
    }
  }
}
void DoSingleFlowFitAndPostProcessing(WorkerInfoQueueItem &item) {
  //printf("=====> CPU Single flow fit and post Processing job\n");
  BkgModelWorkInfo *info = (BkgModelWorkInfo *) (item.private_data);
  FlowBlockSequence::const_iterator flowBlock =
    info->inception_state->bkg_control.signal_chunks.flow_block_sequence.BlockAtFlow( info->flow );
  bool ewscale_correct = info->img->isEmptyWellAmplitudeAvailable();
  int flow_block_id = info->inception_state->bkg_control.signal_chunks.flow_block_sequence.FlowBlockIndex( info->flow );
  info->bkgObj->FitEmbarassinglyParallelRefineFit( flowBlock->size(), flowBlock->begin() );
  info->bkgObj->PreWellCorrectionFactors( ewscale_correct, flowBlock->size(), flowBlock->begin() ); // correct data for anything needed
  
  // export to wells,debug, etc, reset for new set of traces
  info->bkgObj->ExportAllAndReset(info->flow,info->last, flowBlock->size(), info->polyclonal_filter_opts, flow_block_id, flowBlock->begin() ); 
}
void DoInitialBlockOfFlowsRemainingRegionalFit(WorkerInfoQueueItem &item)
{
  //printf("=====> Remaining fit steps job on CPU\n");
  BkgModelWorkInfo *info = (BkgModelWorkInfo *) (item.private_data);
  FlowBlockSequence::const_iterator flowBlock =
    info->inception_state->bkg_control.signal_chunks.flow_block_sequence.BlockAtFlow( info->flow );
  info->bkgObj->RemainingFitStepsForInitialFlowBlock( KEY_LEN, flowBlock->size(), info->table, flowBlock->begin() );
  info->type = SINGLE_FLOW_FIT; 
  if (info->pq->GetGpuQueue() && info->pq->performGpuSingleFlowFitting())
    info->pq->GetGpuQueue()->PutItem(item);
  else
    info->pq->GetCpuQueue()->PutItem(item);
}
void DoInitialBlockOfFlowsAllBeadFit(WorkerInfoQueueItem &item)
{
  //printf("=====> All bead fit job on CPU\n");
  BkgModelWorkInfo *info = (BkgModelWorkInfo *) (item.private_data);
  FlowBlockSequence::const_iterator flowBlock =
    info->inception_state->bkg_control.signal_chunks.flow_block_sequence.BlockAtFlow( info->flow );
  info->bkgObj->FitAllBeadsForInitialFlowBlock( KEY_LEN, flowBlock->size(), info->table, flowBlock->begin() );
  info->type = INITIAL_FLOW_BLOCK_REMAIN_REGIONAL_FIT; 
  info->pq->GetCpuQueue()->PutItem(item);
}