size_t PhaseEstimator::LoadRegion(int region) { if (region_num_reads_[region] == 0) // Nothing to load ? return 0; if (region_reads_[region].size() > 0) // Region already loaded? return 0; ClockTimer timer; timer.StartTimer(); region_reads_[region].reserve(region_num_reads_[region]); int region_x = region % num_regions_x_; int region_y = region / num_regions_x_; int begin_x = region_x * region_size_x_; int begin_y = region_y * region_size_y_; int end_x = min(begin_x + region_size_x_, chip_size_x_); int end_y = min(begin_y + region_size_y_, chip_size_y_); // Mutex needed for wells access, but not needed for region_reads access pthread_mutex_lock(®ion_loader_mutex_); wells_->SetChunk(begin_y, end_y-begin_y, begin_x, end_x-begin_x, 0, flow_order_.num_flows()); wells_->ReadWells(); vector<float> well_buffer(flow_order_.num_flows()); for (int y = begin_y; y < end_y; y++) { for (int x = begin_x; x < end_x; x++) { if (get_subset(x,y) != train_subset_) continue; if (!mask_->Match(x, y, MaskLive)) continue; if (!mask_->Match(x, y, MaskBead)) continue; // A little help from friends in BkgModel if (mask_->Match(x, y, MaskFilteredBadResidual)) continue; if (mask_->Match(x, y, MaskFilteredBadPPF)) continue; if (mask_->Match(x, y, MaskFilteredBadKey)) continue; int cls = 0; if (!mask_->Match(x, y, MaskLib)) { // Not a library bead? cls = 1; if (!mask_->Match(x, y, MaskTF)) // Not a tf bead? continue; } for (int flow = 0; flow < flow_order_.num_flows(); ++flow) well_buffer[flow] = wells_->At(y,x,flow); // Sanity check. If there are NaNs in this read, print warning vector<int> nanflow; for (int flow = 0; flow < flow_order_.num_flows(); ++flow) { if (!isnan(well_buffer[flow])) continue; well_buffer[flow] = 0; nanflow.push_back(flow); } if(nanflow.size() > 0) { fprintf(stderr, "ERROR: BaseCaller read NaNs from wells file, x=%d y=%d flow=%d", x, y, nanflow[0]); for(unsigned int flow=1; flow < nanflow.size(); flow++) { fprintf(stderr, ",%d", nanflow[flow]); } fprintf(stderr, "\n"); fflush(stderr); } region_reads_[region].push_back(BasecallerRead()); if (use_pid_norm_) { region_reads_[region].back().SetDataAndKeyNormalizeNew(&well_buffer[0], flow_order_.num_flows(), keys_[cls].flows(), keys_[cls].flows_length()-1, false /*true*/); } else { region_reads_[region].back().SetDataAndKeyNormalize(&well_buffer[0], flow_order_.num_flows(), keys_[cls].flows(), keys_[cls].flows_length()-1); } bool keypass = true; for (int flow = 0; flow < (keys_[cls].flows_length() - 1); flow++) { if ((int) (region_reads_[region].back().raw_measurements[flow] + 0.5) != keys_[cls][flow]) keypass = false; if (isnan(region_reads_[region].back().raw_measurements[flow])) keypass = false; } if (!keypass) { region_reads_[region].pop_back(); continue; } } } pthread_mutex_unlock(®ion_loader_mutex_); region_num_reads_[region] = region_reads_[region].size(); return timer.GetMicroSec(); }
size_t PhaseEstimator::LoadRegion(int region) { if (region_num_reads_[region] == 0) // Nothing to load ? return 0; if (region_reads_[region].size() > 0) // Region already loaded? return 0; ClockTimer timer; timer.StartTimer(); region_reads_[region].reserve(region_num_reads_[region]); int region_x = region % num_regions_x_; int region_y = region / num_regions_x_; int begin_x = region_x * region_size_x_; int begin_y = region_y * region_size_y_; int end_x = min(begin_x + region_size_x_, chip_size_x_); int end_y = min(begin_y + region_size_y_, chip_size_y_); // Mutex needed for wells access, but not needed for region_reads access pthread_mutex_lock(®ion_loader_mutex_); wells_->SetChunk(begin_y, end_y-begin_y, begin_x, end_x-begin_x, 0, flow_order_.num_flows()); wells_->ReadWells(); vector<float> well_buffer(flow_order_.num_flows()); for (int y = begin_y; y < end_y; y++) { for (int x = begin_x; x < end_x; x++) { if (train_subset_count_ > 0 and get_subset(x,y) != train_subset_) continue; if (!mask_->Match(x, y, MaskLive)) continue; if (!mask_->Match(x, y, MaskBead)) continue; // A little help from friends in BkgModel if (mask_->Match(x, y, MaskFilteredBadResidual)) continue; if (mask_->Match(x, y, MaskFilteredBadPPF)) continue; if (mask_->Match(x, y, MaskFilteredBadKey)) continue; int cls = 0; if (!mask_->Match(x, y, MaskLib)) { // Not a library bead? cls = 1; if (!mask_->Match(x, y, MaskTF)) // Not a tf bead? continue; } for (int flow = 0; flow < flow_order_.num_flows(); ++flow) well_buffer[flow] = wells_->At(y,x,flow); // Sanity check. If there are NaNs in this read, print warning vector<int> nanflow; for (int flow = 0; flow < flow_order_.num_flows(); ++flow) { if (!isnan(well_buffer[flow])) continue; well_buffer[flow] = 0; nanflow.push_back(flow); } if(nanflow.size() > 0) { fprintf(stderr, "ERROR: BaseCaller read NaNs from wells file, x=%d y=%d flow=%d", x, y, nanflow[0]); for(unsigned int flow=1; flow < nanflow.size(); flow++) { fprintf(stderr, ",%d", nanflow[flow]); } fprintf(stderr, "\n"); fflush(stderr); } region_reads_[region].push_back(BasecallerRead()); bool keypass = true; if (key_norm_method_ == "adaptive") { keypass = region_reads_[region].back().SetDataAndKeyNormalizeNew(&well_buffer[0], flow_order_.num_flows(), keys_[cls].flows(), keys_[cls].flows_length()-1, false); } else if (key_norm_method_ == "off") { keypass = region_reads_[region].back().SetDataAndKeyPass(well_buffer, flow_order_.num_flows(), keys_[cls].flows(), keys_[cls].flows_length()-1); } else { keypass = region_reads_[region].back().SetDataAndKeyNormalize(&well_buffer[0], flow_order_.num_flows(), keys_[cls].flows(), keys_[cls].flows_length()-1); } // *** Compute some metrics - overload read.penalty_residual to store them if (keypass) { unsigned int num_zeromer_flows = 0, num_neg_zeromer_flows = 0; double squared_dist_int = 0.0; for (int flow=phasing_start_flow_; flow < phasing_end_flow_; ++flow){ if (region_reads_[region].back().raw_measurements.at(flow) < 0.5) { ++num_zeromer_flows; if (region_reads_[region].back().raw_measurements.at(flow) < 0.0) ++num_neg_zeromer_flows; } if (region_reads_[region].back().raw_measurements.at(flow) < inclusion_threshold_) { double delta = region_reads_[region].back().raw_measurements.at(flow) - round(region_reads_[region].back().raw_measurements.at(flow)); squared_dist_int += delta * delta; } } // Too few zero-mers or too much noise? Moving on along, don't waste time on investigating hopeless candidates. if (num_zeromer_flows < 5 or (float)squared_dist_int > residual_threshold_ + 1.5) keypass = false; else { // [0]=percent_neg_zeromer_flows [1]=squared_dist_int region_reads_[region].back().penalty_residual.assign(2, 0.0f); region_reads_[region].back().penalty_residual.at(0) = (float)num_neg_zeromer_flows / (float)num_zeromer_flows; region_reads_[region].back().penalty_residual.at(1) = squared_dist_int; } } // *** if (not keypass) { region_reads_[region].pop_back(); continue; } } } pthread_mutex_unlock(®ion_loader_mutex_); region_num_reads_[region] = region_reads_[region].size(); return timer.GetMicroSec(); }