//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimWellCollection::calculateIsWellPipesVisible(size_t frameIndex) { if (m_isWellPipesVisible.size() > frameIndex && m_isWellPipesVisible[frameIndex].size()) return; if (m_isWellPipesVisible.size() <= frameIndex) m_isWellPipesVisible.resize(frameIndex+1); if (m_isWellPipesVisible[frameIndex].size() <= wells().size()) m_isWellPipesVisible[frameIndex].resize(wells().size(), false); for (size_t i = 0; i < wells().size(); ++i) { m_isWellPipesVisible[frameIndex][i] = wells[i]->calculateWellPipeVisibility(frameIndex); } }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimSimWellInViewCollection::calculateWellGeometryVisibility(size_t frameIndex) { if (m_framesOfResultWellPipeVisibilities.size() > frameIndex && m_framesOfResultWellPipeVisibilities[frameIndex].size()) return; if (m_framesOfResultWellPipeVisibilities.size() <= frameIndex) m_framesOfResultWellPipeVisibilities.resize(frameIndex+1); if (m_framesOfResultWellPipeVisibilities[frameIndex].size() <= wells().size()) m_framesOfResultWellPipeVisibilities[frameIndex].resize(wells().size(), false); for (const RimSimWellInView* well : wells()) { bool wellPipeVisible = well->isWellPipeVisible(frameIndex); bool wellSphereVisible = well->isWellSpheresVisible(frameIndex); m_framesOfResultWellPipeVisibilities[frameIndex][well->resultWellIndex()] = wellPipeVisible || wellSphereVisible; } }
void StandardWellsSolvent:: computeWellConnectionPressures(const SolutionState& state, const WellState& xw) { if( ! localWellsActive() ) return ; // 1. Compute properties required by computeConnectionPressureDelta(). // Note that some of the complexity of this part is due to the function // taking std::vector<double> arguments, and not Eigen objects. std::vector<double> b_perf; std::vector<double> rsmax_perf; std::vector<double> rvmax_perf; std::vector<double> surf_dens_perf; computePropertiesForWellConnectionPressures(state, xw, b_perf, rsmax_perf, rvmax_perf, surf_dens_perf); const Vector pdepth = perf_cell_depth_; const int nperf = wells().well_connpos[wells().number_of_wells]; const std::vector<double> depth_perf(pdepth.data(), pdepth.data() + nperf); computeWellConnectionDensitesPressures(xw, b_perf, rsmax_perf, rvmax_perf, surf_dens_perf, depth_perf, gravity_); }
int main(int argc, char *argv[]) { // set some defaults char *expDir = "."; bool allreads = false; bool unmappedReads = false; bool lookup = false; // process cmd line args int argcc = 1; while (argcc < argc) { switch (argv[argcc][1]) { case 'e': // set exp dir argcc++; expDir = argv[argcc]; break; case 'a': allreads = true; break; case 'u': unmappedReads = true; break; case 'l': argcc++; lookup = true; LookupInit(argv[argcc]); break; case 'L': argcc++; sscanf(argv[argcc], "%d", &lookupLimit); break; } argcc++; } // crazy, but only way to get rows/cols right now is from mask. Mask mask(1,1); char maskPath[MAX_PATH_LENGTH]; sprintf(maskPath, "%s/bfmask.bin", expDir); mask.SetMask(maskPath); Histogram meanHist(1001, -1.0, 3.0); Histogram stdevZeromerHist(1001, 0.0, 3.0); Histogram stdevOnemerHist(1001, 0.0, 3.0); Histogram avgZeromer(1001, -2.0, 1.0); int w = mask.W(); int h = mask.H(); int validReads[w][h]; memset(validReads, 0, sizeof(validReads)); char blastFile[MAX_PATH_LENGTH]; sprintf(blastFile, "%s/keypass.rpt", expDir); FILE *fp = fopen(blastFile, "r"); if (fp) { char line[256]; while (fgets(line, sizeof(line), fp)) { int row, col; sscanf(line, "r%d|c%d", &row, &col); char *ptr = strrchr(line, '|'); ptr++; double qual; int len; sscanf(ptr, "%lf %d", &qual, &len); validReads[col][row] = 0; if (len > 50 && qual > 0.9) { // look at high quality reads validReads[col][row] |= 1; } if (len > 30 && qual > 0.8) { // look at medium quality reads validReads[col][row] |= 2; } if (len > 20 && !(validReads[col][row] & 4)) validReads[col][row] |= 4; } fclose(fp); } RawWells wells(expDir, "1.wells", mask.H(), mask.W()); wells.OpenForRead(); const WellData *data = NULL; int numFlows = wells.NumFlows(); double measured[numFlows]; int keypassCount = 0; int keypassFailCount = 0; const int numFlowsInKey = 7; int keypassLib[numFlowsInKey] = {1, 0, 1, 0, 0, 1, 0}; // int keypassLib[numFlowsInKey] = {0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1}; // const int numFlowsInKey = 11; int i; int zeromerCount = 0; int onemerCount = 0; double runningAvg0mer = 0.0; double runningAvg1mer = 0.0; double runningAvgN0mer = 0.0; double runningAvgN1mer = 0.0; int runningAvgCount = 0; for(i=0;i<numFlowsInKey;i++) { if (keypassLib[i] == 0) zeromerCount++; if (keypassLib[i] == 1) onemerCount++; } while ((data = wells.ReadNextRegionData()) != NULL) { // look for all live library reads // 1 0 1 0 0 1 0 N - library TCAG key with TACG flow order if (mask.Match(data->x, data->y, MaskLib)) { bool useit = false; if (unmappedReads && validReads[data->x][data->y] == 0) useit = true; else if (!unmappedReads && (allreads || (validReads[data->x][data->y] > 0))) // look at any (4), medium (2), or high(1) quality reads useit = true; if (lookup) { useit = false; if (LookupFind(data->y, data->x)) useit = true; } if (useit) { // do simple keypass on raw well data: // 1 - subtract avg 0-mer // 2 - normalize to avg 1-mer // 3 - threshold to generate vector, compare to 1st 7 flows of known double avg0mer = 0.0; for(i=0;i<numFlowsInKey;i++) { if (keypassLib[i] == 0) avg0mer += data->flowValues[i]; } avg0mer /= zeromerCount; double avg1mer = 0.0; for(i=0;i<numFlowsInKey;i++) { if (keypassLib[i] == 1) avg1mer += data->flowValues[i]; } avg1mer /= onemerCount; // keep a running avg on 0-mer & 1-mer raw key signal runningAvg0mer += avg0mer; runningAvg1mer += avg1mer; runningAvgCount++; // key normalization... avg0mer = 0.0; // force our algorithm to assume weka was right, and 0-mer on avg is already 0 !!! (need to think on this) int flow; for(flow=0;flow<numFlows;flow++) { measured[flow] = data->flowValues[flow] - avg0mer; } double mult = 1.0/avg1mer; for(flow=0;flow<numFlows;flow++) { measured[flow] *= mult; } // calc avg normalized 0-mers & 1-mers double avgN0mer = 0.0; double avgN1mer = 0.0; for(i=0;i<numFlowsInKey;i++) { if (keypassLib[i] == 0) avgN0mer += measured[i]; if (keypassLib[i] == 1) avgN1mer += measured[i]; } avgN0mer /= zeromerCount; avgN1mer /= onemerCount; runningAvgN0mer += avgN0mer; runningAvgN1mer += avgN1mer; // keypass... int keypassVec[numFlowsInKey]; bool keypass = true; for(flow=0;flow<numFlowsInKey;flow++) { keypassVec[flow] = (int)(measured[flow]+0.5); if (keypassVec[flow] != keypassLib[flow]) keypass = false; } if (keypass) { keypassCount++; } else { keypassFailCount++; } // now, lets generate a few metrics and see how they correlate to mapped reads, interest is in mixed fragments // metric1 - the dist between the avg 0-mer and the avg 1-mer - for this, we can usually call the read without cafie corrections for around 40 flows, so we go ahead and do that, then avg the 0-mer and 1-mer signals, then report the mean dist, and the stdev on the 0-mers and 1-mers int numTestFlows = 12; double onemerSig[40]; double zeromerSig[40]; int onemerCount = 0; int zeromerCount = 0; int base; for(flow=numFlowsInKey+1;flow<numTestFlows+numFlowsInKey+1;flow++) { // note we ignore the key base = (int)(measured[flow]+0.5); if (base == 0) { zeromerSig[zeromerCount] = measured[flow]; zeromerCount++; avgZeromer.Add(measured[flow]); } if (base == 1) { onemerSig[onemerCount] = measured[flow]; onemerCount++; } } // if we have sane counts, calc metrics for this read double avgZeroMer = 0.0; double avgOneMer = 0.0; double onemerStdev = 0.0; double zeromerStdev = 0.0; if (zeromerCount > 2 && onemerCount > 2) { int k; for(k=0;k<zeromerCount;k++) { avgZeroMer += zeromerSig[k]; } avgZeroMer /= (double)zeromerCount; for(k=0;k<onemerCount;k++) { avgOneMer += onemerSig[k]; } avgOneMer /= (double)onemerCount; double delta = 0.0; for(k=0;k<zeromerCount;k++) { delta = avgZeroMer - zeromerSig[k]; zeromerStdev += delta*delta; } zeromerStdev = sqrt(zeromerStdev); for(k=0;k<onemerCount;k++) { delta = avgOneMer - onemerSig[k]; onemerStdev += delta*delta; } onemerStdev = sqrt(onemerStdev); meanHist.Add(avgOneMer - avgZeroMer); stdevZeromerHist.Add(zeromerStdev); stdevOnemerHist.Add(onemerStdev); } } } } wells.Close(); // dump some stats printf("Reads: pass/fail/all %d/%d/%d\n", keypassCount, keypassFailCount, keypassCount + keypassFailCount); printf("Avg signals in key: Raw: 0-mer: %.4lf 1-mer: %.4lf Norm: 0-mer: %.4lf 1-mer: %.4lf\n", runningAvg0mer/runningAvgCount, runningAvg1mer/runningAvgCount, runningAvgN0mer/runningAvgCount, runningAvgN1mer/runningAvgCount); meanHist.Dump("AvgDist.txt", 1); stdevZeromerHist.Dump("ZeromerStdev.txt", 1); stdevOnemerHist.Dump("OnemerStdev.txt", 1); avgZeromer.Dump("Avg0mer.txt", 1); }
void StandardWellsSolvent:: computePropertiesForWellConnectionPressures(const SolutionState& state, const WellState& xw, std::vector<double>& b_perf, std::vector<double>& rsmax_perf, std::vector<double>& rvmax_perf, std::vector<double>& surf_dens_perf) { // 1. Compute properties required by computeConnectionPressureDelta(). // Note that some of the complexity of this part is due to the function // taking std::vector<double> arguments, and not Eigen objects. const int nperf = wells().well_connpos[wells().number_of_wells]; const int nw = wells().number_of_wells; // Compute the average pressure in each well block const Vector perf_press = Eigen::Map<const V>(xw.perfPress().data(), nperf); Vector avg_press = perf_press*0; for (int w = 0; w < nw; ++w) { for (int perf = wells().well_connpos[w]; perf < wells().well_connpos[w+1]; ++perf) { const double p_above = perf == wells().well_connpos[w] ? state.bhp.value()[w] : perf_press[perf - 1]; const double p_avg = (perf_press[perf] + p_above)/2; avg_press[perf] = p_avg; } } const std::vector<int>& well_cells = wellOps().well_cells; // Use cell values for the temperature as the wells don't knows its temperature yet. const ADB perf_temp = subset(state.temperature, well_cells); // Compute b, rsmax, rvmax values for perforations. // Evaluate the properties using average well block pressures // and cell values for rs, rv, phase condition and temperature. const ADB avg_press_ad = ADB::constant(avg_press); std::vector<PhasePresence> perf_cond(nperf); for (int perf = 0; perf < nperf; ++perf) { perf_cond[perf] = (*phase_condition_)[well_cells[perf]]; } const PhaseUsage& pu = fluid_->phaseUsage(); DataBlock b(nperf, pu.num_phases); const Vector bw = fluid_->bWat(avg_press_ad, perf_temp, well_cells).value(); if (pu.phase_used[BlackoilPhases::Aqua]) { b.col(pu.phase_pos[BlackoilPhases::Aqua]) = bw; } assert((*active_)[Oil]); assert((*active_)[Gas]); const ADB perf_rv = subset(state.rv, well_cells); const ADB perf_rs = subset(state.rs, well_cells); const Vector perf_so = subset(state.saturation[pu.phase_pos[Oil]].value(), well_cells); if (pu.phase_used[BlackoilPhases::Liquid]) { const Vector bo = fluid_->bOil(avg_press_ad, perf_temp, perf_rs, perf_cond, well_cells).value(); //const V bo_eff = subset(rq_[pu.phase_pos[Oil] ].b , well_cells).value(); b.col(pu.phase_pos[BlackoilPhases::Liquid]) = bo; // const Vector rssat = fluidRsSat(avg_press, perf_so, well_cells); const Vector rssat = fluid_->rsSat(ADB::constant(avg_press), ADB::constant(perf_so), well_cells).value(); rsmax_perf.assign(rssat.data(), rssat.data() + nperf); } else { rsmax_perf.assign(0.0, nperf); } V surf_dens_copy = superset(fluid_->surfaceDensity(0, well_cells), Span(nperf, pu.num_phases, 0), nperf*pu.num_phases); for (int phase = 1; phase < pu.num_phases; ++phase) { if ( phase == pu.phase_pos[BlackoilPhases::Vapour]) { continue; // the gas surface density is added after the solvent is accounted for. } surf_dens_copy += superset(fluid_->surfaceDensity(phase, well_cells), Span(nperf, pu.num_phases, phase), nperf*pu.num_phases); } if (pu.phase_used[BlackoilPhases::Vapour]) { // Unclear wether the effective or the pure values should be used for the wells // the current usage of unmodified properties values gives best match. //V bg_eff = subset(rq_[pu.phase_pos[Gas]].b,well_cells).value(); Vector bg = fluid_->bGas(avg_press_ad, perf_temp, perf_rv, perf_cond, well_cells).value(); Vector rhog = fluid_->surfaceDensity(pu.phase_pos[BlackoilPhases::Vapour], well_cells); // to handle solvent related if (has_solvent_) { const Vector bs = solvent_props_->bSolvent(avg_press_ad,well_cells).value(); //const V bs_eff = subset(rq_[solvent_pos_].b,well_cells).value(); // number of cells const int nc = state.pressure.size(); const ADB zero = ADB::constant(Vector::Zero(nc)); const ADB& ss = state.solvent_saturation; const ADB& sg = ((*active_)[ Gas ] ? state.saturation[ pu.phase_pos[ Gas ] ] : zero); Selector<double> zero_selector(ss.value() + sg.value(), Selector<double>::Zero); Vector F_solvent = subset(zero_selector.select(ss, ss / (ss + sg)),well_cells).value(); Vector injectedSolventFraction = Eigen::Map<const Vector>(&xw.solventFraction()[0], nperf); Vector isProducer = Vector::Zero(nperf); Vector ones = Vector::Constant(nperf,1.0); for (int w = 0; w < nw; ++w) { if(wells().type[w] == PRODUCER) { for (int perf = wells().well_connpos[w]; perf < wells().well_connpos[w+1]; ++perf) { isProducer[perf] = 1; } } } F_solvent = isProducer * F_solvent + (ones - isProducer) * injectedSolventFraction; bg = bg * (ones - F_solvent); bg = bg + F_solvent * bs; const Vector& rhos = solvent_props_->solventSurfaceDensity(well_cells); rhog = ( (ones - F_solvent) * rhog ) + (F_solvent * rhos); } b.col(pu.phase_pos[BlackoilPhases::Vapour]) = bg; surf_dens_copy += superset(rhog, Span(nperf, pu.num_phases, pu.phase_pos[BlackoilPhases::Vapour]), nperf*pu.num_phases); // const Vector rvsat = fluidRvSat(avg_press, perf_so, well_cells); const Vector rvsat = fluid_->rvSat(ADB::constant(avg_press), ADB::constant(perf_so), well_cells).value(); rvmax_perf.assign(rvsat.data(), rvsat.data() + nperf); } else { rvmax_perf.assign(0.0, nperf); } // b and surf_dens_perf is row major, so can just copy data. b_perf.assign(b.data(), b.data() + nperf * pu.num_phases); surf_dens_perf.assign(surf_dens_copy.data(), surf_dens_copy.data() + nperf * pu.num_phases); }