/// <summary> /// Returns the value for given depth, using Logarithmic function /// </summary> /// <param name="srcChannel">Source channel</param> /// <returns>interpolated value</returns> public double GetValueLogarithmicAverage(Oilfield_Channel srcChannel) { double weightedAverage = 0.0; double norm = 0.0; for (int j = 0; j < MapList.Count; j++) { Channel_Resample_Point crp = MapList[j]; double d = srcChannel.Data[crp.Index]; if (Double.IsNaN(d)) { continue; } if (d < 0.000001) { continue; } norm += crp.InverseDistanceWeight; weightedAverage += crp.InverseDistanceWeight * Math.Log10(d); } if (norm <= 0.0) { return(Double.NaN); } return(Math.Pow(10.0, weightedAverage / norm)); }
/// <summary> /// Returns the value for given depth, using Harmonic average /// </summary> /// <param name="srcChannel">Source channel</param> /// <returns>interpolated value</returns> public double GetValueHarmonicAverage(Oilfield_Channel srcChannel) { double weightedAverage = 0.0; double norm = 0.0; for (int j = 0; j < MapList.Count; j++) { Channel_Resample_Point crp = MapList[j]; double d = srcChannel.Data[crp.Index]; if (Double.IsNaN(d)) { continue; } if (d < 0.000001) { continue; } norm += crp.InverseDistanceWeight; weightedAverage += crp.InverseDistanceWeight / d; } if (norm <= 0.0) { return(Double.NaN); } return(norm / weightedAverage); }
/// <summary> /// Returns the value for given depth using linear interpolation method /// </summary> /// <param name="srcChannel">Source channel</param> /// <returns>interpolated value</returns> public double GetValueLinearInterpolate(Oilfield_Channel srcChannel) { if (Above == null || Below == null) { return(Double.NaN); } if (Above.Index == Below.Index) { return(srcChannel.Data[Above.Index]); } double norm = Above.AbsoluteDistance + Below.AbsoluteDistance; if (norm <= 0.0) { return(Double.NaN); } double d1 = srcChannel.Data[Above.Index]; double d2 = srcChannel.Data[Below.Index]; if (Double.IsNaN(d1) || Double.IsNaN(d2)) { return(Double.NaN); } double weightedAverage = d1 * Below.AbsoluteDistance + d2 * Above.AbsoluteDistance; return(weightedAverage / norm); }
/// <summary> /// Computes the displacement relative to the wellhead /// </summary> /// <param name="north_channel_name"></param> /// <param name="TieIn"></param> /// <param name="correction">TVD correction (up-positive)</param> public void ComputeTVD(string tvd_channel_name, string out_channel_name, double correction) { Oilfield_Channel tvd = m_file.GetChannel(tvd_channel_name); if (tvd == null) { throw new Exception("Channel " + tvd_channel_name + " is not found in file " + m_file.FileName); } if (tvd.Data.Count <= 0) { return; } Oilfield_Channel chan = m_file.GetChannel(out_channel_name); if (chan == null) { throw new Exception("Channel " + out_channel_name + " is not found in file " + m_file.FileName); } if (chan.Data.Count <= 0) { return; } for (int i = 0; i < chan.Data.Count; i++) { chan.Data[i] = tvd.Data[i] - correction; } }
/// <summary> /// Resamples all channels in a file /// </summary> public void Resample(Oilfield_File srcFile, Oilfield_File dstFile, int default_method) { for (int i = 1; i < dstFile.Channels.Count; i++) { Oilfield_Channel c = dstFile.GetChannel(i); if ((c.Name.ToLower().Contains("az") || c.Name.ToLower().Contains("ti")) && c.Unit.ToLower().StartsWith("deg")) { this.Resample(srcFile.GetChannel(i), c, LinearInterpolateAngle); continue; } if (c.Unit.ToLower().Equals("m") || c.Unit.ToLower().Equals("ft") || c.Unit.ToLower().Equals("ms") || c.Unit.ToLower().Equals("s")) { this.Resample(srcFile.GetChannel(i), c, LinearInterpolate); continue; } if (c.Unit.ToLower().StartsWith("ohm")) { this.Resample(srcFile.GetChannel(i), c, LogarithmicAverage); continue; } if (c.Unit.ToLower().StartsWith("mho")) { this.Resample(srcFile.GetChannel(i), c, HarmonicAverage); continue; } this.Resample(srcFile.GetChannel(i), c, default_method); } }
/// <summary> /// Creates an Resample engine (with the processing map) /// </summary> /// <param name="srcIndex">Source index</param> /// <param name="dstIndex">Destimation index</param> /// <param name="minWindow">Search Window to include initially</param> public Channel_Resample(Oilfield_Channel srcIndex, Oilfield_Channel dstIndex, double minWindow) { m_DstIndex = dstIndex; double maxWindow = Double.MinValue; for (int i = 1; i < srcIndex.Data.Count; i++) { if (Double.IsNaN(srcIndex.Data[i]) || Double.IsNaN(srcIndex.Data[i - 1])) { continue; } double d = Math.Abs(srcIndex.Data[i] - srcIndex.Data[i - 1]); if (d > maxWindow) { maxWindow = d; } } maxWindow *= 2.0; if (maxWindow < minWindow) { maxWindow = minWindow; } for (int i = 0; i < dstIndex.Data.Count; i++) { m_mapping.Add(new Channel_Resample_Map(srcIndex, dstIndex.Data[i], minWindow, maxWindow)); } }
/// <summary> /// Constructor. Crates a merge class. Note: the merge is performed on memory only. /// </summary> /// <param name="source">File to take information from</param> /// <param name="destination">File to save the information into</param> public Data_Merge(Oilfield_File source, Oilfield_File destination) { m_src = source; m_dst = destination; double step = 0.0; double step2 = 0.0; try { step = Math.Abs(Convert.ToDouble(m_dst.GetConstant("STEP"))); step2 = Math.Abs(Convert.ToDouble(m_src.GetConstant("STEP"))); } catch (Exception) { } if (step < 0.001) { step = 0.001; } Oilfield_Channel src_Index = source.GetIndex(); Oilfield_Channel dest_Index = destination.GetIndex(); if (step2 < 0.001 && src_Index.Data.Count > 2) { step2 = Math.Abs(src_Index.Data[1] - src_Index.Data[0]); } step2 = 2.0 * Math.Max(step, step2); m_Resampler = new Channel_Resample(src_Index, dest_Index, step * 0.5, step2); }
private void ComputeFromBottom(Oilfield_Channel depth, Oilfield_Channel azim, Oilfield_Channel tilt, Oilfield_Channel northing, Oilfield_Channel easting, Oilfield_Channel tvd, Oilfield_Channel dls) { int l = depth.Data.Count - 1; tvd.Data[l] = depth.Data[l]; northing.Data[l] = 0.0; easting.Data[l] = 0.0; dls.Data[l] = 0.0; for (int i = l - 1; i >= 0; i--) { double dMD = depth.Data[i] - depth.Data[i + 1]; double A1 = 0.0; double I1 = 0.0; double A2 = 0.0; double I2 = 0.0; if (Double.IsNaN(azim.Data[i + 1]) || Double.IsNaN(tilt.Data[i + 1])) { if (!Double.IsNaN(azim.Data[i]) && Double.IsNaN(tilt.Data[i])) { A1 = azim.Data[i] * Math.PI / 180.0; I1 = tilt.Data[i] * Math.PI / 180.0; A2 = azim.Data[i] * Math.PI / 180.0; I2 = tilt.Data[i] * Math.PI / 180.0; } } else if (Double.IsNaN(azim.Data[i]) || Double.IsNaN(tilt.Data[i])) { if (!Double.IsNaN(azim.Data[i + 1]) && Double.IsNaN(tilt.Data[i + 1])) { A1 = azim.Data[i + 1] * Math.PI / 180.0; I1 = tilt.Data[i + 1] * Math.PI / 180.0; A2 = azim.Data[i + 1] * Math.PI / 180.0; I2 = tilt.Data[i + 1] * Math.PI / 180.0; } } else { A1 = azim.Data[i + 1] * Math.PI / 180.0; I1 = tilt.Data[i + 1] * Math.PI / 180.0; A2 = azim.Data[i] * Math.PI / 180.0; I2 = tilt.Data[i] * Math.PI / 180.0; } double dl = Math.Acos(Math.Cos(I2 - I1) - Math.Sin(I1) * Math.Sin(I2) * (1.0 - Math.Cos(A2 - A1))); double rf = 1.0; if (Math.Abs(dl) > 0.00001) { rf = 2.0 * Math.Tan(dl * 0.5) / dl; } double dTVD = 0.5 * dMD * (Math.Cos(I1) + Math.Cos(I2)) * rf; double dN = 0.5 * dMD * (Math.Sin(I1) * Math.Cos(A1) + Math.Sin(I2) * Math.Cos(A2)) * rf; double dE = 0.5 * dMD * (Math.Sin(I1) * Math.Sin(A1) + Math.Sin(I2) * Math.Sin(A2)) * rf; tvd.Data[i] = tvd.Data[i + 1] + dTVD; northing.Data[i] = northing.Data[i + 1] + dN; easting.Data[i] = easting.Data[i + 1] + dE; dls.Data[i] = dl * 30.0; } }
/// <summary> /// Despike the channel from lower outliers /// </summary> /// <param name="name">channel name in the source file</param> /// <param name="threshold">relative value of threshold</param> public void DespikeFromLow(string name, double threshold) { Oilfield_Channel src_index = m_src.GetIndex(); if (src_index == null) { return; } Oilfield_Channel src_channel = m_src.GetChannel(name); if (src_channel == null) { return; } // locate upper and lower boundaries and determine threshold DataStart = Double.NaN; DataEnd = Double.NaN; DataStartIndex = -1; DataEndIndex = -1; if (!src_channel.LocateDataBoundaries(src_index)) { return; } DataStart = src_channel.DataStart; DataEnd = src_channel.DataEnd; DataStartIndex = src_channel.DataStartIndex; DataEndIndex = src_channel.DataEndIndex; double tr = src_channel.Average * threshold; // remove all values below threshhold for (int i = 0; i < src_channel.Data.Count; i++) { double d = src_channel.Data[i]; if (Double.IsNaN(d)) { continue; } if (d < tr) { src_channel.Data[i] = Double.NaN; } } // compute average of the remaining and fill the gaps double avr = src_channel.GetAverage(DataStartIndex, DataEndIndex); for (int i = 0; i < src_channel.Data.Count; i++) { if (i < DataStartIndex || i > DataEndIndex) { continue; } if (Double.IsNaN(src_channel.Data[i])) { src_channel.Data[i] = avr; } } }
/// <summary> /// Returns the value for given depth, using ClosestPoint function from Above /// </summary> /// <param name="srcChannel">Source channel</param> /// <returns>interpolated value</returns> public double GetValueStepFromAbove(Oilfield_Channel srcChannel) { if (Above == null) { return(Double.NaN); } return(srcChannel.Data[Above.Index]); }
/// <summary> /// Returns the value for given depth, using ClosestPoint function from below /// </summary> /// <param name="srcChannel">Source channel</param> /// <returns>interpolated value</returns> public double GetValueStepFromBelow(Oilfield_Channel srcChannel) { if (Below == null) { return(Double.NaN); } return(srcChannel.Data[Below.Index]); }
/// <summary> /// Returns the value for given depth, using ClosestPoint function /// </summary> /// <param name="srcChannel">Source channel</param> /// <returns>interpolated value</returns> public double GetValueClosestPoint(Oilfield_Channel srcChannel) { if (Closest == null) { return(Double.NaN); } return(srcChannel.Data[Closest.Index]); }
/// <summary> /// Creates an Resample engine (with the processing map) /// </summary> /// <param name="srcIndex">Source index</param> /// <param name="dstIndex">Destimation index</param> /// <param name="minWindow">Search Window to include initially</param> /// <param name="maxWindow">Search Window to pass the empty values through</param> public Channel_Resample(Oilfield_Channel srcIndex, Oilfield_Channel dstIndex, double minWindow, double maxWindow) { m_DstIndex = dstIndex; for (int i = 0; i < dstIndex.Data.Count; i++) { m_mapping.Add(new Channel_Resample_Map(srcIndex, dstIndex.Data[i], minWindow, maxWindow)); } }
/// <summary> /// Returns the value for given depth, interpolating through 360 degrees /// </summary> /// <param name="srcChannel">Source channel</param> /// <returns>interpolated value</returns> public double GetValueLinearInterpolateAngle(Oilfield_Channel srcChannel) { if (Above == null || Below == null) { return(Double.NaN); } if (Above.Index == Below.Index) { return(srcChannel.Data[Above.Index]); } double norm = Above.AbsoluteDistance + Below.AbsoluteDistance; if (norm <= 0.0) { return(Double.NaN); } double d1 = srcChannel.Data[Above.Index]; double d2 = srcChannel.Data[Below.Index]; if (Double.IsNaN(d1) || Double.IsNaN(d2)) { return(Double.NaN); } while (d1 < 0.0) { d1 += 360.0; } while (d1 > 360.0) { d1 -= 360.0; } while (d2 < 0.0) { d2 += 360.0; } while (d2 > 360.0) { d2 -= 360.0; } if (d1 == d2) { return(d1); } double weightedAverage = d1 * Below.AbsoluteDistance + d2 * Above.AbsoluteDistance; weightedAverage /= norm; //if (d2 - d1 > 180.0) weightedAverage += 180.0; //if (d1 - d2 > 180.0) weightedAverage += 180.0; while (weightedAverage < 0.0) { weightedAverage += 360.0; } while (weightedAverage > 360.0) { weightedAverage -= 360.0; } return(weightedAverage); }
private void InitMap(Oilfield_Channel srcIndex, double depth, double minWindow, double maxWindow) { if (depth < srcIndex.MinValue - minWindow) { return; } if (depth > srcIndex.MaxValue + minWindow) { return; } for (int j = 0; j < 20; j++) { MapList.Clear(); bool above_exists = false; bool below_exists = false; for (int i = 0; i < srcIndex.Data.Count; i++) { double d = srcIndex.Data[i]; if (Double.IsNaN(d)) { continue; } if (d < depth - minWindow || depth + minWindow < d) { continue; } double dd = d - depth; above_exists = above_exists && (dd <= 0.0); below_exists = below_exists && (dd >= 0.0); MapList.Add(new Channel_Resample_Point(i, dd)); } minWindow *= 2.0; if (minWindow > maxWindow) { break; } if (MapList.Count >= 5 && above_exists && below_exists) { break; } } double weight = 0.0; for (int j = 0; j < MapList.Count; j++) { weight += MapList[j].AbsoluteDistance; } if (weight < 1e-6) { weight = 1e-6; } weight = 1.0 / weight; for (int j = 0; j < MapList.Count; j++) { MapList[j].Normalize(weight); } }
/// <summary> /// Returns the deep copy of LAS channel /// </summary> public new CSV_Channel GetChannelCopy(int index) { if (index < 0 || index >= Channels.Count) { return(null); } Oilfield_Channel c = GetChannel(index).Clone(); return((CSV_Channel)c); }
/// <summary> /// Returns the value for given depth, interpolating through 360 degrees /// </summary> /// <param name="srcChannel">Source channel</param> /// <returns>interpolated value</returns> public double GetValueAverageAngle(Oilfield_Channel srcChannel) { if (MapList.Count < 0) { return(Double.NaN); } if (MapList.Count == 1) { return(srcChannel.Data[MapList[0].Index]); } double weightedAverage = 0.0; double norm = 0.0; for (int j = 0; j < MapList.Count; j++) { Channel_Resample_Point crp = MapList[j]; double d = srcChannel.Data[crp.Index]; if (Double.IsNaN(d)) { continue; } while (d < 0.0) { d += 360.0; } while (d > 360.0) { d -= 360.0; } double n = crp.InverseDistanceWeight; if (weightedAverage - d > 180.0) { d += 180.0; } if (d - weightedAverage > 180.0) { d += 180.0; } weightedAverage = norm * weightedAverage + n * d; norm += n; if (norm > 0.0) { weightedAverage /= norm; } while (weightedAverage < 0.0) { weightedAverage += 360.0; } while (weightedAverage >= 360.0) { weightedAverage -= 360.0; } } return(weightedAverage); }
/// <summary> /// Computes the classic min curvature algorithm /// </summary> /// <param name="azimuth_channel_name"></param> /// <param name="tilt_channel_name"></param> /// <param name="northing_channel_name"></param> /// <param name="easting_channel_name"></param> /// <param name="tvd_channel_name"></param> /// <param name="dls_channel_name"></param> public void Compute(string azimuth_channel_name, string tilt_channel_name, string northing_channel_name, string easting_channel_name, string tvd_channel_name, string dls_channel_name) { if (m_file == null) { return; } Oilfield_Channel depth = m_file.GetIndex(); Oilfield_Channel azim = m_file.GetChannel(azimuth_channel_name); if (azim == null) { throw new Exception("Channel " + azimuth_channel_name + " is not found in file " + m_file.FileName); } Oilfield_Channel tilt = m_file.GetChannel(tilt_channel_name); if (tilt == null) { throw new Exception("Channel " + tilt_channel_name + " is not found in file " + m_file.FileName); } Oilfield_Channel northing = m_file.GetOrCreateChannel(northing_channel_name, "M", "Northing coordinate", "0.000"); if (northing == null) { throw new Exception("Channel " + northing_channel_name + " cannot be created"); } Oilfield_Channel easting = m_file.GetOrCreateChannel(easting_channel_name, "M", "Easting coordinate", "0.000"); if (easting == null) { throw new Exception("Channel " + easting_channel_name + " cannot be created"); } Oilfield_Channel tvd = m_file.GetOrCreateChannel(tvd_channel_name, "M", "True vertical depth", "0.000"); if (tvd == null) { throw new Exception("Channel " + tvd_channel_name + " cannot be created"); } Oilfield_Channel dls = m_file.GetOrCreateChannel(dls_channel_name, "deg/30M", "Dogleg severity", "0.000"); if (dls == null) { throw new Exception("Channel " + dls_channel_name + " cannot be created"); } if (depth.Data[0] < depth.Data[depth.Data.Count - 1]) { ComputeFromTop(depth, azim, tilt, northing, easting, tvd, dls); } else { ComputeFromBottom(depth, azim, tilt, northing, easting, tvd, dls); } }
/// <summary> /// Creates the same channes as in the given file /// </summary> /// <param name="file"></param> public override void CreateSameChannels(Oilfield_File file) { for (int i = 1; i < file.Channels.Count; i++) { Oilfield_Channel lc = file.Channels[i]; Oilfield_Channel tmp = this.GetChannel(lc.Name); if (tmp != null) { continue; } this.GetOrCreateChannel(lc.Name, lc.Unit, lc.Description, lc.Format); } }
/// <summary> /// Creates a deep copy of a given channel /// </summary> /// <param name="c"></param> public Petrolog_Channel(Oilfield_Channel c) : base((Oilfield_Channel)c) { if (c.GetType() != this.GetType()) { return; } Petrolog_Channel input = (Petrolog_Channel)c; this.m_Node = input.m_Node; this.m_Parent = input.m_Parent; this.LogType = input.LogType; this.LogColumn = input.LogColumn; this.LogNumber = input.LogNumber; this.LogTool = input.LogTool; this.LogDimension = input.LogDimension; this.LogColumnStart = input.LogColumnStart; }
/// <summary> /// Creates a single resample map; makes interpolation adjustments /// </summary> /// <param name="srcIndex">Depth index of the source file</param> /// <param name="depth">depth at the destination file</param> /// <param name="window">initial window size</param> public Channel_Resample_Map(Oilfield_Channel srcIndex, double depth, double minWindow, double maxWindow) { InitMap(srcIndex, depth, minWindow, maxWindow); if (MapList.Count <= 0) { return; } List <Channel_Resample_Point> above = new List <Channel_Resample_Point>(); List <Channel_Resample_Point> below = new List <Channel_Resample_Point>(); foreach (Channel_Resample_Point crp in MapList) { if (crp.Distance <= 0.0) { above.Add(crp); } if (crp.Distance >= 0.0) { below.Add(crp); } } double ad_above = Double.MaxValue; for (int i = 0; i < above.Count; i++) { if (above[i].AbsoluteDistance > ad_above) { continue; } Above = above[i]; ad_above = Above.AbsoluteDistance; } double ad_below = Double.MaxValue; for (int i = 0; i < below.Count; i++) { if (below[i].AbsoluteDistance > ad_below) { continue; } Below = below[i]; ad_below = Below.AbsoluteDistance; } Closest = (ad_below < ad_above) ? Below : Above; }
/// <summary> /// Corrects the channel for arbitrary tie-in /// </summary> /// <param name="channel_name"></param> /// <param name="TieIn"></param> public void CorrectToTiein(string channel_name, double TieIn) { Oilfield_Channel chan = m_file.GetChannel(channel_name); if (chan == null) { throw new Exception("Channel " + channel_name + " is not found in file " + m_file.FileName); } if (chan.Data.Count <= 0) { return; } double delta = TieIn - chan.Data[0]; for (int i = 0; i < chan.Data.Count; i++) { chan.Data[i] += delta; } }
/// <summary> /// Extract the channel from source and merges to the destination /// </summary> /// <param name="name">channel name in the source file</param> public void MergeChannel(string name, int method) { Oilfield_Channel src_channel = m_src.GetChannel(name); if (src_channel == null) { return; } Oilfield_Channel dst_channel = m_dst.GetChannel(name); if (dst_channel == null) { dst_channel = m_dst.GetNewChannel(src_channel); m_dst.Channels.Add(dst_channel); } else { dst_channel.SetData(Double.NaN); } m_Resampler.Resample(src_channel, dst_channel, method); }
/// <summary> /// Returns the value for given depth using Gaussian method /// </summary> /// <param name="srcChannel">Source channel</param> /// <returns>interpolated value</returns> public double GetValueGaussianAverage(Oilfield_Channel srcChannel) { double weightedAverage = 0.0; double norm = 0.0; for (int j = 0; j < MapList.Count; j++) { Channel_Resample_Point crp = MapList[j]; double d = srcChannel.Data[crp.Index]; if (Double.IsNaN(d)) { continue; } norm += crp.GaussianWeight; weightedAverage += crp.GaussianWeight * d; } if (norm <= 0.0) { return(Double.NaN); } return(weightedAverage / norm); }
/// <summary> /// Computes the displacement relative to the wellhead /// </summary> /// <param name="north_channel_name"></param> /// <param name="TieIn"></param> public void ComputeDisplacement(string north_channel_name, string east_channel_name, string disp_channel_name) { Oilfield_Channel nort = m_file.GetChannel(north_channel_name); if (nort == null) { throw new Exception("Channel " + north_channel_name + " is not found in file " + m_file.FileName); } if (nort.Data.Count <= 0) { return; } Oilfield_Channel east = m_file.GetChannel(east_channel_name); if (east == null) { throw new Exception("Channel " + east_channel_name + " is not found in file " + m_file.FileName); } if (east.Data.Count <= 0) { return; } Oilfield_Channel chan = m_file.GetChannel(disp_channel_name); if (chan == null) { throw new Exception("Channel " + disp_channel_name + " is not found in file " + m_file.FileName); } if (chan.Data.Count <= 0) { return; } for (int i = 0; i < chan.Data.Count; i++) { double d = nort.Data[i] * nort.Data[i] + east.Data[i] * east.Data[i]; chan.Data[i] = Math.Sqrt(d); } }
/// <summary> /// Filter the channel using Ganning Algorithm /// </summary> /// <param name="name">channel name in the source file</param> /// <param name="n">half-size of filter</param> /// <param name="k">number of rejected values</param> public void FilterChannelGunning(string name, int n, int k) { Oilfield_Channel src_index = m_src.GetIndex(); if (src_index == null) { return; } Oilfield_Channel src_channel = m_src.GetChannel(name); if (src_channel == null) { return; } // locate upper and lower boundaries DataStart = Double.NaN; DataEnd = Double.NaN; DataStartIndex = -1; DataEndIndex = -1; if (!src_channel.LocateDataBoundaries(src_index)) { return; } DataStart = src_channel.DataStart; DataEnd = src_channel.DataEnd; DataStartIndex = src_channel.DataStartIndex; DataEndIndex = src_channel.DataEndIndex; // perform Gunning filtering int l = src_channel.Data.Count; List <double> buff = new List <double>(l); buff.AddRange(src_channel.Data); for (int i = 0; i < l; i++) { src_channel.Data[i] = Double.NaN; if (i < DataStartIndex) { continue; } if (i > DataEndIndex) { continue; } List <double> tmp = new List <double>((n << 1) + 1); for (int j = i - n; j <= i + n; j++) { if (j < 0 || j >= l) { continue; } if (Double.IsNaN(buff[j])) { continue; } tmp.Add(buff[j]); } if (tmp.Count <= 0) { continue; } tmp.Sort(); int kk = k; while (tmp.Count < (kk + 5 + kk)) { kk--; } double avearge = 0.0; double avearge_count = 0.0; for (int j = kk; j < tmp.Count - kk; j++) { avearge += tmp[j]; avearge_count += 1.0; } if (avearge_count <= 0.0) { continue; } src_channel.Data[i] = avearge / avearge_count; } }
/// <summary> /// Interpolate the channel /// </summary> /// <param name="name">channel name in the source file</param> /// <param name="isAzimuth">st to true is wrap-around is needed</param> private void InterpolateChannelRaw(string name, bool isAzimuth) { Oilfield_Channel src_index = m_src.GetIndex(); if (src_index == null) { return; } Oilfield_Channel src_channel = m_src.GetChannel(name); if (src_channel == null) { return; } // locate upper and lower boundaries DataStart = Double.NaN; DataEnd = Double.NaN; DataStartIndex = -1; DataEndIndex = -1; if (!src_channel.LocateDataBoundaries(src_index)) { return; } DataStart = src_channel.DataStart; DataEnd = src_channel.DataEnd; DataStartIndex = src_channel.DataStartIndex; DataEndIndex = src_channel.DataEndIndex; // perform interpolation for missing lines for (int i = 0; i < src_channel.Data.Count; i++) { if (!Double.IsNaN(src_channel.Data[i])) { continue; } if (i < DataStartIndex) { continue; } if (i > DataEndIndex) { continue; } double d = Convert.ToDouble(i); double depth1 = 0.0; double a1 = 0.0; for (int j = i; j >= 0; j--) { if (Double.IsNaN(src_channel.Data[j])) { continue; } depth1 = Convert.ToDouble(j); a1 = src_channel.Data[j]; break; } double depth2 = 1.0; double a2 = 0.0; for (int j = i; j < src_channel.Data.Count; j++) { if (Double.IsNaN(src_channel.Data[j])) { continue; } depth2 = Convert.ToDouble(j); a2 = src_channel.Data[j]; break; } double dd = depth2 - depth1; if (Math.Abs(dd) < 0.001) { continue; } double w1 = (depth2 - d) / dd; double w2 = (d - depth1) / dd; if (isAzimuth) { if (a1 > 270.0 && a2 < 90.0) { a1 -= 360.0; } if (a1 < 90.0 && a2 > 270.0) { a2 -= 360.0; } } src_channel.Data[i] = w1 * a1 + w2 * a2; if (isAzimuth) { while (src_channel.Data[i] < 0.0) { src_channel.Data[i] += 360.0; } while (src_channel.Data[i] >= 360.0) { src_channel.Data[i] -= 360.0; } } } }
/// <summary> /// Resamples a single channel /// </summary> /// <param name="srcChannel"></param> /// <param name="dstChannel"></param> public void Resample(Oilfield_Channel srcChannel, Oilfield_Channel dstChannel, int method) { List <double> tmp = new List <double>(); switch (method) { case LinearInterpolate: for (int i = 0; i < m_DstIndex.Data.Count; i++) { tmp.Add(m_mapping[i].GetValueLinearInterpolate(srcChannel)); } break; case InverseDistanceAverage: for (int i = 0; i < m_DstIndex.Data.Count; i++) { tmp.Add(m_mapping[i].GetValueInverseDistanceAverage(srcChannel)); } break; case InverseSquareDistanceAverage: for (int i = 0; i < m_DstIndex.Data.Count; i++) { tmp.Add(m_mapping[i].GetValueInverseSquareDistanceAverage(srcChannel)); } break; case GaussianAverage: for (int i = 0; i < m_DstIndex.Data.Count; i++) { tmp.Add(m_mapping[i].GetValueGaussianAverage(srcChannel)); } break; case LinearInterpolateAngle: for (int i = 0; i < m_DstIndex.Data.Count; i++) { tmp.Add(m_mapping[i].GetValueLinearInterpolateAngle(srcChannel)); } break; case AverageAngle: for (int i = 0; i < m_DstIndex.Data.Count; i++) { tmp.Add(m_mapping[i].GetValueAverageAngle(srcChannel)); } break; case StepFromAbove: for (int i = 0; i < m_DstIndex.Data.Count; i++) { tmp.Add(m_mapping[i].GetValueStepFromAbove(srcChannel)); } break; case StepFromBelow: for (int i = 0; i < m_DstIndex.Data.Count; i++) { tmp.Add(m_mapping[i].GetValueStepFromBelow(srcChannel)); } break; case LogarithmicAverage: for (int i = 0; i < m_DstIndex.Data.Count; i++) { tmp.Add(m_mapping[i].GetValueLogarithmicAverage(srcChannel)); } break; case HarmonicAverage: for (int i = 0; i < m_DstIndex.Data.Count; i++) { tmp.Add(m_mapping[i].GetValueHarmonicAverage(srcChannel)); } break; default: for (int i = 0; i < m_DstIndex.Data.Count; i++) { tmp.Add(m_mapping[i].GetValueClosestPoint(srcChannel)); } break; } dstChannel.Data = tmp; }
/// <summary> /// Draws the log line /// </summary> /// <param name="source"></param> /// <param name="g"></param> /// <summary> public override void Draw(string source, Graphics g, Bitmap baseBitmap) { Oilfield_Channel chX = null; Oilfield_Channel chY = null; try { GetDataFile(source); } catch (Exception ex) { throw new Exception(ex.Message); } foreach (Oilfield_Channel oc in LastLog.Channels) { if (oc.Name == Name_x) { chX = oc; } if (oc.Name == Name_y) { chY = oc; } } if (chX == null && LastLog.Channels.Count > Order_x) { chX = LastLog.Channels[Order_x]; } if (chY == null && LastLog.Channels.Count > Order_y) { chY = LastLog.Channels[Order_y]; } if (chX == null) { throw new Exception("File " + Text + " has no " + Name_x); } if (chY == null) { throw new Exception("File " + Text + " has no " + Name_y); } try { Rectangle destRectangle = new Rectangle(x, y, dx + 1, dy + 1); g.SetClip(destRectangle); Brush myBrush = new SolidBrush(Slide.GetColor(FrontColor)); Pen myPen = new Pen(myBrush, LineSize); myPen.DashPattern = GetDashStyle(); List <PointF> myPoints = new List <PointF>(); int i = 0; while (i < chX.Data.Count && i < chY.Data.Count) { plotPointScaled(g, myPen, myPoints, chX.Data[i], chY.Data[i]); i++; } // while if (myPoints.Count > 1) // draw the remaining points, if any { g.DrawLines(myPen, myPoints.ToArray()); } } catch (Exception ex) { throw new Exception(ex.Message); } finally { if (g != null) { g.ResetClip(); } } }
/// <summary> /// Creates a deep copy of a given channel /// </summary> /// <param name="c"></param> public LAS_Channel(Oilfield_Channel c): base( (Oilfield_Channel)c) { }