using System.Collections.Generic;
using static Reliability.PrioritizationModelFactors;
using System.Security.Cryptography;
using System.Net.NetworkInformation;
public static class Extenstions
public static int MaxIndex<T>(this IEnumerable<T> sequence)
foreach (T value in sequence)
if (value.CompareTo(maxValue) > 0 || maxIndex == -1)
public static T2 ToCode<T1, T2>(this Dictionary<T1, T2> dict, T1 name, T2 DefaultCode)
return !(name is null) && dict.ContainsKey(name) ? dict[name] : DefaultCode;
public static int IntervalIndex<T>(this IEnumerable<T> ordered_sequence, T val)
foreach (T item in ordered_sequence)
if (item.CompareTo(val) >= 0)
public enum InternalCoatingCode
public enum OuterCoatingOrICCPCode
public enum DiagnocticCode
public enum SoilCorrosivityCode
public enum CorrosionRateCode
public enum FluidVelocityCode
public class PrioritizationData
public float Length { get; set; }
public int CommissioningYear { get; set; }
public float Diameter { get; set; }
public float Thickness { get; set; }
public int MaterialCode { get; set; }
public string Material { get; set; }
public int PurposePipelineCode { get; set; }
public string PurposePipeline { get; set; }
public InternalCoatingCode InternalCoating { get; set; }
public bool IsInhibition { get; set; }
public OuterCoatingOrICCPCode OuterCoatingOrICCP { get; set; }
public bool IsPigging { get; set; }
public DiagnocticCode Diagnoctic { get; set; }
public CorrosionRateCode AvgCorrosionRate { get; set; }
public H2SCode H2S { get; set; }
public SoilCorrosivityCode Soil { get; set; }
public bool? StrayCurrents { get; set; }
public float InletPressure { get; set; }
public FluidVelocityCode FluidVelocity { get; set; }
public WaterCutCode WaterCut { get; set; }
public int? DefectNum { get; set; }
public int CurrentInternalCorrosionFailures { get; set; }
public int CurrentOuterCorrosionFailures { get; set; }
public int CurrentAge { get; set; }
public int LastInternalCorrosionFailures { get; set; }
public int LastOuterCorrosionFailures { get; set; }
public int LastAge { get; set; }
public int YearInternalCorrosionFailures { get; set; }
public int YearOuterCorrosionFailures { get; set; }
public int YearAge { get; set; }
public int AllInternalCorrosionFailures { get; set; }
public int AllOuterCorrosionFailures { get; set; }
public float LengthAge => Length * CurrentAge;
public float SumInternalCorrosionFailures => (DefectNum ?? 0 + YearInternalCorrosionFailures + LastInternalCorrosionFailures + CurrentInternalCorrosionFailures);
public float SumOuterCorrosionFailures => (YearOuterCorrosionFailures + LastOuterCorrosionFailures + CurrentOuterCorrosionFailures);
public bool RegulatoryCompliance { get; set; }
public float? RejectionThickness { get; set; }
public bool UnresolvedInvalidDefects { get; set; }
public float DamageUnit { get; set; }
public int RepairedDefectNumbers { get; set; }
public OperatorNameCode OperatorName { get; set; }
public LandCategoryCode LandCategory { get; set; }
public FailoverPlanTimeCode FailoverPlanTime { get; set; }
public LayingPipelineCode LayingPipeline { get; set; }
public string WaterBodyLocation { get; set; }
public PipelineTypeCode PipelineType { get; set; }
public float OilDensity { get; set; }
public float WaterDensity { get; set; }
public float GasDensity { get; set; }
public float OutletPressure { get; set; }
public float WaterCutValue { get; set; }
public float OilRate { get; set; }
public class PrioritizationFileData
public float Length { get; set; }
public int CommissioningYear { get; set; }
public float Diameter { get; set; }
public float Thickness { get; set; }
public string MaterialName { get; set; }
public string PurposePipelineName { get; set; }
public string InternalCoating { get; set; }
public string Inhibition { get; set; }
public string OuterCoatingOrICCP { get; set; }
public int? SER { get; set; }
public int? AcousticEmission { get; set; }
public int? ILI { get; set; }
public int? HI { get; set; }
public int? SI { get; set; }
public int? UD { get; set; }
public string Pigging { get; set; }
public float? AvgCorrosionRate { get; set; }
public string H2S { get; set; }
public string Soil { get; set; }
public string StrayCurrents { get; set; }
public float? WaterCut { get; set; }
public float? Pin { get; set; }
public float? Pout { get; set; }
public float? Qoil { get; set; }
public float? Qliq { get; set; }
public float? Qgas { get; set; }
public int? DefectNum { get; set; }
public int? CurrentInternalCorrosionFailures { get; set; }
public int? CurrentOuterCorrosionFailures { get; set; }
public int? LastInternalCorrosionFailures { get; set; }
public int? LastOuterCorrosionFailures { get; set; }
public int? YearInternalCorrosionFailures { get; set; }
public int? YearOuterCorrosionFailures { get; set; }
public int? AllInternalCorrosionFailures { get; set; }
public int? AllOuterCorrosionFailures { get; set; }
public bool RegulatoryCompliance { get; set; }
public float? RejectionThickness { get; set; }
public bool UnresolvedInvalidDefects { get { return UnresolvedInvalidDefectNumbers - RepairedUnresolvedInvalidDefectNumbers > 0; } }
public float DamageUnit { get; set; }
public int NextYearDefectNumbers { get; set; }
public int UnresolvedInvalidDefectNumbers { get; set; }
public int RepairedNextYearDefectNumbers { get; set; }
public int RepairedUnresolvedInvalidDefectNumbers { get; set; }
public int RepairedDefectNumbers { get; set; }
public string OperatorName { get; set; }
public string LandCategory { get; set; }
public string FailoverPlanTime { get; set; }
public string LayingPipeline { get; set; }
public string WaterBodyLocation { get; set; }
public string PipelineType { get; set; }
public float? OilDensity { get; set; }
public float? WaterDensity { get; set; }
public float? GasDensity { get; set; }
public PrioritizationData ToPrioritizationData(int CurrentYear)
return new PrioritizationData()
CommissioningYear = CommissioningYear,
Diameter = this.Diameter,
Thickness = this.Thickness,
MaterialCode = ToMaterialCode(MaterialName),
PurposePipelineCode = ToPurposePipeline(PurposePipelineName),
PurposePipeline = PurposePipelineName,
InternalCoating = ToInternalCoating(InternalCoating),
IsInhibition = ToIsInhibition(Inhibition),
OuterCoatingOrICCP = ToOuterCoatingOrICCP(OuterCoatingOrICCP),
IsPigging = ToIsPigging(Pigging),
Diagnoctic = ToDiagnostic(2023, SER, AcousticEmission, ILI, HI, SI, UD),
AvgCorrosionRate = ToAvgCorrosionRate(AvgCorrosionRate),
StrayCurrents = ToStrayCurrents(StrayCurrents),
WaterCut = ToWaterCut(WaterCut, ToPurposePipeline(PurposePipelineName)),
InletPressure = Pin ?? 0,
FluidVelocity = ToFluidVelocity(Pin, Pout, WaterCut, Qliq, Qgas,
this.Diameter, this.Thickness,
ToPurposePipeline(PurposePipelineName)),
CurrentInternalCorrosionFailures = ToCorrosionFailures(CurrentInternalCorrosionFailures),
CurrentOuterCorrosionFailures = ToCorrosionFailures(CurrentOuterCorrosionFailures),
CurrentAge = CurrentYear - CommissioningYear,
LastInternalCorrosionFailures = ToCorrosionFailures(LastInternalCorrosionFailures),
LastOuterCorrosionFailures = ToCorrosionFailures(LastOuterCorrosionFailures),
LastAge = CurrentYear - CommissioningYear - 1,
YearInternalCorrosionFailures = ToCorrosionFailures(YearInternalCorrosionFailures),
YearOuterCorrosionFailures = ToCorrosionFailures(YearOuterCorrosionFailures),
YearAge = CurrentYear - CommissioningYear - 2,
AllInternalCorrosionFailures = ToCorrosionFailures(AllInternalCorrosionFailures),
AllOuterCorrosionFailures = ToCorrosionFailures(AllOuterCorrosionFailures),
RegulatoryCompliance = RegulatoryCompliance,
RejectionThickness = RejectionThickness,
UnresolvedInvalidDefects = UnresolvedInvalidDefects,
OperatorName = ToOperatorNameCode(OperatorName),
LandCategory = ToLandCategoryCode(LandCategory),
FailoverPlanTime = ToFailoverPlanTimeCode(FailoverPlanTime),
LayingPipeline = ToLayingPipelineCode(LayingPipeline),
WaterBodyLocation = WaterBodyLocation,
PipelineType = ToPipelineTypeCode(PipelineType),
OilDensity = OilDensity ?? 850f,
WaterDensity = WaterDensity ?? 1000f,
GasDensity = GasDensity ?? 0.8f,
OutletPressure = Pout ?? 0f,
WaterCutValue = WaterCut ?? 0f,
public int ToMaterialCode(string name)
return (new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase)
{"Неметаллическое покрытие",5},
public InternalCoatingCode ToInternalCoating(string name)
return (new Dictionary<string, InternalCoatingCode>(StringComparer.OrdinalIgnoreCase)
{"Секции стальных труб, футерованных полиэтиленом (СФП)", InternalCoatingCode.polyethylene },
{"Порошковое покрытие", InternalCoatingCode.powder },
{"Эпоксидное покрытие", InternalCoatingCode.epoxy },
{"Лакокрасочное покрытие", InternalCoatingCode.paintwork },
{"Порошково-эпоксидное покрытие", InternalCoatingCode.powder_epoxy },
{"Нет покрытия", InternalCoatingCode.no },
}).ToCode(name, InternalCoatingCode.no);
public int ToPurposePipeline(string name)
return (new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase)
{"Водовод низк. давл. товарной воды", 1 },
{"Водовод низк. давл. пресной воды", 4 },
{"Нефтепровод внешнего транспорта", 2 },
{"Вык. лин. одиночных скв.", 5 },
{"Водовод выс. давл.", 3 },
{"Газопроводы выс. давл.", 8 },
{"Газопроводы низк. давл.", 7 },
{"Напорные нефтепроводы", 6 },
{"Нефтесборные сети", 5 },
public bool ToIsInhibition(string name)
return (new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase)
public OuterCoatingOrICCPCode ToOuterCoatingOrICCP(string name)
return (new Dictionary<string, OuterCoatingOrICCPCode>(StringComparer.OrdinalIgnoreCase)
{"Без покрытия и ЭХЗ", OuterCoatingOrICCPCode.no },
{"с защитным покрытием без защиты ЭХЗ", OuterCoatingOrICCPCode.coating },
{"с отсутствием защитного покрытия имеющие ЭХЗ", OuterCoatingOrICCPCode.ICCP },
{"с защитным покрытием и ЭХЗ", OuterCoatingOrICCPCode.coating_ICCP },
}).ToCode(name, OuterCoatingOrICCPCode.no);
public bool ToIsPigging(string name)
return (new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase)
{"Не проводится", false},
public CorrosionRateCode ToAvgCorrosionRate(float? val)
val.Value <= 0.01f ? CorrosionRateCode.no
: val.Value <= 0.1f ? CorrosionRateCode.low
: val.Value <= 0.5f ? CorrosionRateCode.avg
: CorrosionRateCode.no_data;
public H2SCode ToH2S(string name)
return (new Dictionary<string, H2SCode>(StringComparer.OrdinalIgnoreCase)
{"отсутствует ", H2SCode.no },
{"низкое", H2SCode.low },
{"среднее", H2SCode.avg },
{"высокое", H2SCode.high },
{"нет данных", H2SCode.no_data },
}).ToCode(name, H2SCode.no);
public DiagnocticCode ToDiagnostic(int CurrentYear, int? SER, int? AcousticEmission, int? ILI, int? HI, int? SI, int? UD)
if (SER.HasValue && SER.Value > CurrentYear)
return DiagnocticCode.ser;
else if (AcousticEmission.HasValue && AcousticEmission.Value > CurrentYear)
return DiagnocticCode.ae;
if (ILI.HasValue && ILI.Value > CurrentYear)
return DiagnocticCode.ili;
if (HI.HasValue && HI.Value > CurrentYear)
return DiagnocticCode.hi;
if (SI.HasValue && SI.Value > CurrentYear)
return DiagnocticCode.si;
if (UD.HasValue && UD.Value > CurrentYear)
return DiagnocticCode.ud;
return DiagnocticCode.no;
public SoilCorrosivityCode ToSoil(string name)
return (new Dictionary<string, SoilCorrosivityCode>(StringComparer.OrdinalIgnoreCase)
{"Низкое", SoilCorrosivityCode.low },
{"Среднее", SoilCorrosivityCode.avg },
{"Высокое", SoilCorrosivityCode.high },
{"Нет данных", SoilCorrosivityCode.no_data },
}).ToCode(name, SoilCorrosivityCode.no_data);
public bool? ToStrayCurrents(string name)
return (new Dictionary<string, bool?>(StringComparer.OrdinalIgnoreCase)
public WaterCutCode ToWaterCut(float? val, int purpose)
return WaterCut.Value >= 65 ? WaterCutCode.high : WaterCutCode.low;
else return WaterCutCode.high;
return WaterCutCode.mono;
public bool IsWaterPipeline(int purpose)
return purpose == 1 || purpose == 3 || purpose == 4;
public bool IsOilPipeline(int purpose)
return purpose == 5 || purpose == 6;
public bool IsOtherPipeline(int purpose)
return purpose == 2 || purpose == 7 || purpose == 8;
public FluidVelocityCode ToFluidVelocity(float? Pin, float? Pout, float? wc, float? Qliq, float? Qgas, float D, float Thickness, int purpose)
var Pavg = Pin.HasValue && Pout.HasValue ? (Pin + Pout) / 2 : Pin.HasValue ? Pin.Value : Pout ?? 0;
var velocity = (Ql + Qg * 1000 / (Pavg + 1)) / 3600 / 24 / (3.14 * Math.Pow((D - 2 * Thickness) / 1000, 2) / 4);
if (IsWaterPipeline(purpose))
return velocity <= 1 ? FluidVelocityCode.water_low : FluidVelocityCode.water_high;
if (IsOilPipeline(purpose) && velocity <= 0.8)
return FluidVelocityCode.oil_water_low;
else if (IsOilPipeline(purpose) && velocity <= 4.5)
return FluidVelocityCode.oil_water_medium;
else if (IsOilPipeline(purpose) && velocity > 4.5)
return FluidVelocityCode.oil_water_high;
if (IsOilPipeline(purpose) && velocity <= 0.6)
return FluidVelocityCode.water_oil_low;
else if (IsOilPipeline(purpose) && velocity <= 1.5)
return FluidVelocityCode.water_oil_medium;
else if (IsOilPipeline(purpose) && velocity > 1.5)
return FluidVelocityCode.water_oil_high;
else if (IsOtherPipeline(purpose))
return FluidVelocityCode.other;
return FluidVelocityCode.error;
return FluidVelocityCode.error;
public int ToCorrosionFailures(int? val)
return val.HasValue ? val.Value : 0;
public OperatorNameCode ToOperatorNameCode(string name)
return (new Dictionary<string, OperatorNameCode>(StringComparer.OrdinalIgnoreCase)
{"Ванкорнефть", OperatorNameCode.Vankorneft },
{"Варьёганнефтегаз", OperatorNameCode.Varyoganneftegaz },
{"Востсибнефтегаз", OperatorNameCode.Vostsibneftegaz },
{"ВЧНГ", OperatorNameCode.VCNG },
{"Грознефтегаз", OperatorNameCode.Grozneftegaz },
{"Дагнефть", OperatorNameCode.Dagneft },
{"Дагнефтегаз", OperatorNameCode.Dagneftegaz },
{"Ингнефть", OperatorNameCode.Ingneft },
{"Краснодарнефтегаз", OperatorNameCode.Krasnodarneftegaz },
{"Нягань", OperatorNameCode.Nyagan },
{"Оренбургнефть", OperatorNameCode.Orenburgneft },
{"Полярное Сияние", OperatorNameCode.PolarLights },
{"Пурнефтегаз", OperatorNameCode.Purneftegaz },
{"Роспан", OperatorNameCode.Rospan },
{"Самаранефтегаз", OperatorNameCode.Samaraneftegaz },
{"Самотлорнефтегаз", OperatorNameCode.Samotlorneftegaz },
{"Сахалинморнефтегаз", OperatorNameCode.Sakhalinmorneftegaz },
{"Северная нефть", OperatorNameCode.NorthernOil },
{"Ставропольнефтегаз", OperatorNameCode.Stavropolneftegaz },
{"Томскнефть", OperatorNameCode.Tomskneft },
{"Уват", OperatorNameCode.Uvat },
{"Удмуртнефть", OperatorNameCode.Udmurtneft },
{"Юганскнефтегаз", OperatorNameCode.Yuganskneftegaz },
{"Башнефть-Добыча", OperatorNameCode.BashneftDobycha }
}).ToCode(name, OperatorNameCode.Yuganskneftegaz);
public LandCategoryCode ToLandCategoryCode(string name)
return (new Dictionary<string, LandCategoryCode>(StringComparer.OrdinalIgnoreCase)
{"Земли промышленности", LandCategoryCode.industrial_lands },
{"Особо охраняемые территории", LandCategoryCode.specially_protected_areas },
{"Горные пастбища", LandCategoryCode.mountain_pastures },
{"Водоохранные зоны", LandCategoryCode.water_protection_zones },
{"Сельскохозяйственные", LandCategoryCode.agricultural },
{"Облесенные территории", LandCategoryCode.forest_lands },
{"Земли населенных пунктов", LandCategoryCode.settlement_lands },
{"Зона производственного назначения", LandCategoryCode.industrial_designation_zone },
{"Зона специального назначения", LandCategoryCode.special_purpose_zone },
{"Зона инженерных и транспортных инфраструктур", LandCategoryCode.engineering_and_transport_infrastructures_zone },
{"Зона военных объектов", LandCategoryCode.military_objects_zone },
{"Прочие", LandCategoryCode.other },
}).ToCode(name, LandCategoryCode.other);
public FailoverPlanTimeCode ToFailoverPlanTimeCode(string name)
return (new Dictionary<string, FailoverPlanTimeCode>(StringComparer.OrdinalIgnoreCase)
{"≤ 6", FailoverPlanTimeCode.l6 },
{"≤ 12", FailoverPlanTimeCode.l12 },
{"≤ 18", FailoverPlanTimeCode.l18 },
{"≤ 24", FailoverPlanTimeCode.l24 },
{"≤ 30", FailoverPlanTimeCode.l30 },
{"≤ 36", FailoverPlanTimeCode.l36 },
{"≤ 48", FailoverPlanTimeCode.l48 },
{"≤ 60", FailoverPlanTimeCode.l60 },
{"≤ 72", FailoverPlanTimeCode.l72 },
{"≤ 84", FailoverPlanTimeCode.l84 },
{"≤ 96", FailoverPlanTimeCode.l96 },
{"≤ 108", FailoverPlanTimeCode.l108 },
{"≤ 120", FailoverPlanTimeCode.l120 },
{"≤ 132", FailoverPlanTimeCode.l132 },
{"> 6", FailoverPlanTimeCode.g132 },
}).ToCode(name, FailoverPlanTimeCode.g132);
public LayingPipelineCode ToLayingPipelineCode(string name)
return (new Dictionary<string, LayingPipelineCode>(StringComparer.OrdinalIgnoreCase)
{"Болото", LayingPipelineCode.swamp },
{"Горная местность", LayingPipelineCode.mountainous_area },
{"Родовые угодья", LayingPipelineCode.Rangelands },
{"Зона общественного внимания", LayingPipelineCode.public_attention_area },
{"Земли частной собственности", LayingPipelineCode.private_property_lands },
{"Коррозионно-активный грунт", LayingPipelineCode.corrosive_soil },
{"Водный объект", LayingPipelineCode.water_body },
{"Пересечение оврагов, ручьев", LayingPipelineCode.ravines_streams_crossing },
{"Прочие", LayingPipelineCode.other },
}).ToCode(name, LayingPipelineCode.other);
public PipelineTypeCode ToPipelineTypeCode(string name)
return (new Dictionary<string, PipelineTypeCode>(StringComparer.OrdinalIgnoreCase)
{"Линейный трубопровод", PipelineTypeCode.line },
{"Водный переход", PipelineTypeCode.water_crossings },
{"Пересечение ж/д магистралей", PipelineTypeCode.railway_crossing },
{"Пересечение дорог федерального значения", PipelineTypeCode.federal_roads_crossing },
}).ToCode(name, PipelineTypeCode.line);
public class PrioritizationModelFactors
public PrioritizationModelFactors()
LastYearFailure = new Dictionary<string, float>();
AllFailure = new Dictionary<string, float>();
FailureProbability = new Dictionary<string, float>();
InternalCoating = new Dictionary<string, float>();
PipeMaterial = new Dictionary<string, float>();
PurposePipeline = new Dictionary<string, float>();
Inhibition = new Dictionary<string, float>();
CorrosionRate = new Dictionary<string, float>();
H2S = new Dictionary<string, float>();
Currents = new Dictionary<string, float>();
SoilCorrosivity = new Dictionary<string, float>();
OuterCoating = new Dictionary<string, float>();
WaterCut = new Dictionary<string, float>();
FluidVelocity = new Dictionary<string, float>();
Inspection = new Dictionary<string, float>();
Pigging = new Dictionary<string, float>();
CriticalAge = new Dictionary<string, int>();
public float BaseFactor => NotZero(Math.Max(
Math.Max(FailureProbability.Max(o => o.Value), InternalCoating.Max(o => o.Value)),
Math.Max(PipeMaterial.Max(o => o.Value), PurposePipeline.Max(o => o.Value))
Math.Max(Inhibition.Max(o => o.Value), CorrosionRate.Max(o => o.Value)),
Math.Max(H2S.Max(o => o.Value), Currents.Max(o => o.Value))
Math.Max(SoilCorrosivity.Max(o => o.Value), OuterCoating.Max(o => o.Value)),
Math.Max(WaterCut.Max(o => o.Value), FluidVelocity.Max(o => o.Value))
Math.Max(Inspection.Max(o => o.Value), Pigging.Max(o => o.Value)),
public float NotZero(float val) => val <= 0 ? 1 : val;
internal static class FailureCodes
public static string FromFailure(int FailureNum)
if (FailureNum == 0) return cat1;
else if (FailureNum >= 1 && FailureNum <= 2) return cat2;
else if (FailureNum >= 3 && FailureNum <= 4) return cat3;
else if (FailureNum >= 5) return cat4;
throw new NotImplementedException();
public const string cat1 = "0";
public const string cat2 = "1-2";
public const string cat3 = "3-4";
public const string cat4 = "≥ 5";
internal static class WaterCutCodes
public static string FromWaterCutCode(WaterCutCode code)
case WaterCutCode.low: return cat1;
case WaterCutCode.high: return cat2;
case WaterCutCode.mono: return cat3;
throw new NotImplementedException();
public const string cat1 = "менее 65";
public const string cat2 = "более 65";
public const string cat3 = "Трубопроводы с одной средой";
internal static class FailureProbabilityCodes
public static string FromAge(int age)
else if (age >= 5 && age < 10)
else if (age >= 10 && age < 15)
else if (age >= 15 && age < 20)
else if (age >= 20 && age < 25)
else if (age >= 25 && age < 30)
throw new NotImplementedException();
public const string cat1 = "< 5 лет";
public const string cat2 = "5-10 лет";
public const string cat3 = "10-15 лет";
public const string cat4 = "15-20 лет";
public const string cat5 = "20-25 лет";
public const string cat6 = "25-30 лет";
public const string cat7 = "> 30 лет";
internal static class InternalCoatingCodes
public static string FromInternalCoatingCode(InternalCoatingCode code)
case InternalCoatingCode.polyethylene: return cat1;
case InternalCoatingCode.powder: return cat2;
case InternalCoatingCode.epoxy: return cat3;
case InternalCoatingCode.paintwork: return cat4;
case InternalCoatingCode.powder_epoxy: return cat5;
case InternalCoatingCode.no: return cat6;
throw new NotImplementedException();
public const string cat1 = "Секции стальных труб, футерованных полиэтиленом (СФП)";
public const string cat2 = "Порошковое покрытие";
public const string cat3 = "Эпоксидное покрытие";
public const string cat4 = "Лакокрасочное покрытие";
public const string cat5 = "Порошково-эпоксидное покрытие";
public const string cat6 = "Нет покрытия";
internal static class PipeMaterialCodes
public static string FromMaterialCode(int code)
throw new NotImplementedException();
public const string cat1 = "1";
public const string cat2 = "2";
public const string cat3 = "3";
public const string cat4 = "4";
public const string cat5 = "5";
public const string cat6 = "6";
public const string cat7 = "7";
internal static class PurposePipelineCodes
public const string cat1 = "Водовод низк. давл. товарной воды";
public const string cat2 = "Водовод низк. давл. пресной воды";
public const string cat3 = "Водовод выс. давл.";
public const string cat4 = "Газопроводы выс. давл.";
public const string cat5 = "Газопроводы низк. давл.";
public const string cat6 = "Напорные нефтепроводы";
public const string cat7 = "Нефтесборные сети";
public const string cat8 = "Нефтепровод внешнего транспорта";
public const string cat9 = "Вык. лин. одиночных скв.";
internal static class InhibitionCodes
public static string FromInhibition(bool code) => code ? cat2 : cat1;
public const string cat1 = "Нет, нет данных";
public const string cat2 = "Да";
internal static class CorrosionRateCodes
public static string FromCorrosionRateCode(CorrosionRateCode code)
case CorrosionRateCode.no: return cat1;
case CorrosionRateCode.low: return cat2;
case CorrosionRateCode.avg: return cat3;
case CorrosionRateCode.high: return cat4;
case CorrosionRateCode.no_data: return cat5;
throw new NotImplementedException();
public const string cat1 = "до 0,01 включительно";
public const string cat2 = "от 0,01 до 0,1";
public const string cat3 = "от 0,1 до 0,5";
public const string cat4 = "Свыше 0,5";
public const string cat5 = "Нет данных";
internal static class H2SCodes
public static string FromH2SCode(H2SCode code)
case H2SCode.no: return cat1;
case H2SCode.low: return cat2;
case H2SCode.avg: return cat3;
case H2SCode.high: return cat4;
case H2SCode.no_data: return cat5;
throw new NotImplementedException();
public const string cat1 = "Отсутствует";
public const string cat2 = "Низкое";
public const string cat3 = "Среднее";
public const string cat4 = "Высокое";
public const string cat5 = "Нет данных";
internal static class CurrentsCodes
public static string FromCurrentsCode(bool? code)
else return code.Value ? cat2 : cat1;
throw new NotImplementedException();
public const string cat1 = "Нет";
public const string cat2 = "Да";
public const string cat3 = "Нет данных";
internal static class SoilCorrosivityCodes
public static string FromSoilCorrosivityCode(SoilCorrosivityCode code)
case SoilCorrosivityCode.low: return cat1;
case SoilCorrosivityCode.avg: return cat2;
case SoilCorrosivityCode.high: return cat3;
case SoilCorrosivityCode.no_data: return cat4;
throw new NotImplementedException();
public const string cat1 = "Низкая";
public const string cat2 = "Средняя";
public const string cat3 = "Высокая";
public const string cat4 = "Нет данных";
internal static class OuterCoatingCodes
public static string FromOuterCoatingCode(OuterCoatingOrICCPCode code)
case OuterCoatingOrICCPCode.no: return cat1;
case OuterCoatingOrICCPCode.coating: return cat2;
case OuterCoatingOrICCPCode.ICCP: return cat3;
case OuterCoatingOrICCPCode.coating_ICCP: return cat4;
throw new NotImplementedException();
public const string cat1 = "Без покрытия и ЭХЗ";
public const string cat2 = "с защитным покрытием без защиты ЭХЗ";
public const string cat3 = "с отсутствием защитного покрытия имеющиеЭХЗ";
public const string cat4 = "с защитным покрытием и ЭХЗ";
internal static class FluidVelocityCodes
public static string FromFluidVelocityCode(FluidVelocityCode code)
case FluidVelocityCode.water_low: return cat1;
case FluidVelocityCode.water_high: return cat2;
case FluidVelocityCode.oil_water_low: return cat3;
case FluidVelocityCode.oil_water_medium: return cat4;
case FluidVelocityCode.oil_water_high: return cat5;
case FluidVelocityCode.water_oil_low: return cat6;
case FluidVelocityCode.water_oil_medium: return cat7;
case FluidVelocityCode.water_oil_high: return cat8;
case FluidVelocityCode.other: return cat9;
throw new NotImplementedException();
public const string cat1 = "Водоводы до 1м/с";
public const string cat2 = "Водоводы свыше 1м/с";
public const string cat3 = "Нефтесборные и напорные трубопроводы до 0,8 м/с включительно (обводненность менее 65% включительно)";
public const string cat4 = "Нефтесборные и напорные трубопроводы от 0,8 до 4,5 м/с (обводненность менее 65% включительно)";
public const string cat5 = "Нефтесборные и напорные трубопроводы свыше 4,5 м/с (обводненность менее 65% включительно)";
public const string cat6 = "Нефтесборные и напорные трубопроводы до 0,6 м/с включительно (обводненность более 65%)";
public const string cat7 = "Нефтесборные и напорные трубопроводы от 0,6 до 1,5 м/с (обводненность более 65%)";
public const string cat8 = "Нефтесборные и напорные трубопроводы свыше 1,5 м/с (обводненность более 65%)";
public const string cat9 = "Прочие трубопроводы";
internal static class InspectionCodes
public static string FromDiagnocticCode(DiagnocticCode code)
case DiagnocticCode.no: return cat1;
case DiagnocticCode.ser: return cat2;
case DiagnocticCode.ae: return cat3;
case DiagnocticCode.ili: return cat4;
case DiagnocticCode.hi: return cat5;
case DiagnocticCode.si: return cat6;
case DiagnocticCode.ud: return cat7;
throw new NotImplementedException();
public const string cat1 = "Отсутствует, не проводилась";
public const string cat2 = "ЭПБ";
public const string cat3 = "АЭД";
public const string cat4 = "ВТД";
public const string cat5 = "Гидравлические испытания";
public const string cat6 = "Стресс-испытания";
public const string cat7 = "Ультразвуковая толщинометрия";
internal static class PiggingCodes
public static string FromPigging(bool code) => code ? cat1 : cat2;
public const string cat1 = "Проводится";
public const string cat2 = "Не проводится";
public Dictionary<string, float> LastYearFailure { get; set; }
public Dictionary<string, float> WaterCut { get; set; }
public Dictionary<string, float> AllFailure { get; set; }
public Dictionary<string, float> FailureProbability { get; set; }
public Dictionary<string, float> InternalCoating { get; set; }
public Dictionary<string, float> PipeMaterial { get; set; }
public Dictionary<string, float> PurposePipeline { get; set; }
public Dictionary<string, float> Inhibition { get; set; }
public Dictionary<string, float> CorrosionRate { get; set; }
public Dictionary<string, float> H2S { get; set; }
public Dictionary<string, float> Currents { get; set; }
public Dictionary<string, float> SoilCorrosivity { get; set; }
public Dictionary<string, float> OuterCoating { get; set; }
public Dictionary<string, float> FluidVelocity { get; set; }
public Dictionary<string, float> Inspection { get; set; }
public Dictionary<string, float> Pigging { get; set; }
public Dictionary<string, int> CriticalAge { get; set; }
public override string ToString()
return string.Join(Environment.NewLine, LastYearFailure.Union(AllFailure).Union(FailureProbability)
.Union(InternalCoating).Union(PipeMaterial).Union(PurposePipeline).Union(Inhibition)
.Union(CorrosionRate).Union(H2S).Union(SoilCorrosivity).Union(Currents)
.Union(OuterCoating).Union(Inspection).Union(Pigging).Union(WaterCut)
public class PrioritizationModel
public int CurrentYear { get; set; }
public PrioritizationModel(int CurrentYear)
this.CurrentYear = CurrentYear;
public PrioritizationData[] Convert(PrioritizationFileData[] file)
return file.Select(o => o.ToPrioritizationData(CurrentYear)).ToArray();
public PrioritizationModelFactors Fit(PrioritizationFileData[] file)
return this.Fit(this.Convert(file));
public static float[] NormilizeFactors(float[] factors)
var new_factors = new float[factors.Length];
for (int i = 0; i < factors.Length; i++)
new_factors[i] = factors[i] / min;
if (i > 0 && new_factors[i] < new_factors[i - 1])
new_factors[i] = new_factors[i - 1];
public static float fun1(int idx, float[] failures, float[] lens)
if (failures[idx] > 0 && lens[idx] > 0)
return failures[idx] / lens[idx];
else return failures.Sum() / lens.Sum();
public static float[] sum2(PrioritizationData[] data, Func<PrioritizationData, bool>[] conds, Func<PrioritizationData, float> agg)
return conds.Select(o => data.Where(o).Sum(agg)).ToArray();
public static void FitLastYearFailure(PrioritizationModelFactors factors, PrioritizationData[] data)
var conds = new Func<PrioritizationData, bool>[] {
o => o.LastInternalCorrosionFailures == 0,
o => o.LastInternalCorrosionFailures == 1 || o.LastInternalCorrosionFailures == 2,
o => o.LastInternalCorrosionFailures == 3 || o.LastInternalCorrosionFailures == 4,
o => o.LastInternalCorrosionFailures >= 5 };
var lens = sum2(data, conds, o => o.Length);
var failures = sum2(data, conds, o => o.CurrentInternalCorrosionFailures);
var tmp = NormilizeFactors(failures.Zip(lens, (x, y) => x > 0 && y > 0 ? x / y : failures.Sum() / lens.Sum()).ToArray());
factors.LastYearFailure[PrioritizationModelFactors.FailureCodes.cat1] = tmp[0];
factors.LastYearFailure[PrioritizationModelFactors.FailureCodes.cat2] = tmp[1];
factors.LastYearFailure[PrioritizationModelFactors.FailureCodes.cat3] = tmp[2];
factors.LastYearFailure[PrioritizationModelFactors.FailureCodes.cat4] = tmp[3];
public static void FitAllYearFailure(PrioritizationModelFactors factors, PrioritizationData[] data)
var avgLengthAge = data.Sum(o => o.LengthAge) / data.Sum(o => o.Length);
var conds = new Func<PrioritizationData, bool>[] {
o => o.AllInternalCorrosionFailures == 0,
o => o.AllInternalCorrosionFailures == 1 || o.AllInternalCorrosionFailures == 2,
o => o.AllInternalCorrosionFailures == 3 || o.AllInternalCorrosionFailures == 4,
o => o.AllInternalCorrosionFailures >= 5 };
var lens = sum2(data, conds, o => o.Length);
var failures = sum2(data, conds, o => o.AllInternalCorrosionFailures);
var tmp = (failures.Zip(lens, (x, y) => (x > 0 && y > 0 ? x / y : failures.Sum() / lens.Sum()) / avgLengthAge).ToArray());
factors.AllFailure[PrioritizationModelFactors.FailureCodes.cat1] = tmp[0];
factors.AllFailure[PrioritizationModelFactors.FailureCodes.cat2] = tmp[1];
factors.AllFailure[PrioritizationModelFactors.FailureCodes.cat3] = tmp[2];
factors.AllFailure[PrioritizationModelFactors.FailureCodes.cat4] = tmp[3];
public static void FitFailureProbability(PrioritizationModelFactors factors, PrioritizationData[] data)
var CurrentConds = new Func<PrioritizationData, bool>[] {
o => o.CurrentAge >= 0 && o.CurrentAge < 5,
o => o.CurrentAge >= 5 && o.CurrentAge < 10,
o => o.CurrentAge >= 10 && o.CurrentAge < 15,
o => o.CurrentAge >= 15 && o.CurrentAge < 20,
o => o.CurrentAge >= 20 && o.CurrentAge < 25,
o => o.CurrentAge >= 25 && o.CurrentAge < 30,
o => o.CurrentAge >= 30 };
var LastConds = new Func<PrioritizationData, bool>[] {
o => o.LastAge >= 0 && o.LastAge < 5,
o => o.LastAge >= 5 && o.LastAge < 10,
o => o.LastAge >= 10 && o.LastAge < 15,
o => o.LastAge >= 15 && o.LastAge < 20,
o => o.LastAge >= 20 && o.LastAge < 25,
o => o.LastAge >= 25 && o.LastAge < 30,
var YearConds = new Func<PrioritizationData, bool>[] {
o => o.YearAge >= 0 && o.YearAge < 5,
o => o.YearAge >= 5 && o.YearAge < 10,
o => o.YearAge >= 10 && o.YearAge < 15,
o => o.YearAge >= 15 && o.YearAge < 20,
o => o.YearAge >= 20 && o.YearAge < 25,
o => o.YearAge >= 25 && o.YearAge < 30,
var lens = sum2(data, CurrentConds, o => o.Length).Zip(sum2(data, LastConds, o => o.Length), (x, y) => x + y).Zip(sum2(data, YearConds, o => o.Length), (x, y) => x + y);
var failures = sum2(data, CurrentConds, o => o.CurrentInternalCorrosionFailures).Zip(sum2(data, LastConds, o => o.LastInternalCorrosionFailures), (x, y) => x + y).Zip(sum2(data, YearConds, o => o.YearInternalCorrosionFailures), (x, y) => x + y);
var tmp = failures.Zip(lens, (x, y) => x / y).ToArray();
factors.FailureProbability[PrioritizationModelFactors.FailureProbabilityCodes.cat1] = tmp[0];
factors.FailureProbability[PrioritizationModelFactors.FailureProbabilityCodes.cat2] = tmp[1];
factors.FailureProbability[PrioritizationModelFactors.FailureProbabilityCodes.cat3] = tmp[2];
factors.FailureProbability[PrioritizationModelFactors.FailureProbabilityCodes.cat4] = tmp[3];
factors.FailureProbability[PrioritizationModelFactors.FailureProbabilityCodes.cat5] = tmp[4];
factors.FailureProbability[PrioritizationModelFactors.FailureProbabilityCodes.cat6] = tmp[5];
factors.FailureProbability[PrioritizationModelFactors.FailureProbabilityCodes.cat7] = tmp[6];
public static void FitInternalCoating(PrioritizationModelFactors factors, PrioritizationData[] data)
var CurrentConds = new Func<PrioritizationData, bool>[] {
o => o.InternalCoating == InternalCoatingCode.polyethylene && o.CurrentAge >=0,
o => o.InternalCoating == InternalCoatingCode.powder && o.CurrentAge >=0,
o => o.InternalCoating == InternalCoatingCode.epoxy && o.CurrentAge >=0,
o => o.InternalCoating == InternalCoatingCode.paintwork && o.CurrentAge >=0,
o => o.InternalCoating == InternalCoatingCode.powder_epoxy && o.CurrentAge >=0,
o => o.InternalCoating == InternalCoatingCode.no && o.CurrentAge >=0 };
var LastConds = new Func<PrioritizationData, bool>[] {
o => o.InternalCoating == InternalCoatingCode.polyethylene && o.LastAge >=0,
o => o.InternalCoating == InternalCoatingCode.powder && o.LastAge >=0,
o => o.InternalCoating == InternalCoatingCode.epoxy && o.LastAge >=0,
o => o.InternalCoating == InternalCoatingCode.paintwork && o.LastAge >=0,
o => o.InternalCoating == InternalCoatingCode.powder_epoxy && o.LastAge >=0,
o => o.InternalCoating == InternalCoatingCode.no && o.LastAge >=0 };
var YearConds = new Func<PrioritizationData, bool>[] {
o => o.InternalCoating == InternalCoatingCode.polyethylene && o.YearAge >=0,
o => o.InternalCoating == InternalCoatingCode.powder && o.YearAge >=0,
o => o.InternalCoating == InternalCoatingCode.epoxy && o.YearAge >=0,
o => o.InternalCoating == InternalCoatingCode.paintwork && o.YearAge >=0,
o => o.InternalCoating == InternalCoatingCode.powder_epoxy && o.YearAge >=0,
o => o.InternalCoating == InternalCoatingCode.no && o.YearAge >=0 };
var conds = new Func<PrioritizationData, bool>[] {
o => o.InternalCoating == InternalCoatingCode.polyethylene,
o => o.InternalCoating == InternalCoatingCode.powder,
o => o.InternalCoating == InternalCoatingCode.epoxy,
o => o.InternalCoating == InternalCoatingCode.paintwork,
o => o.InternalCoating == InternalCoatingCode.powder_epoxy,
o => o.InternalCoating == InternalCoatingCode.no };
var lens = sum2(data, CurrentConds, o => o.Length).Zip(sum2(data, LastConds, o => o.Length), (x, y) => x + y).Zip(sum2(data, YearConds, o => o.Length), (x, y) => x + y);
var failures = sum2(data, conds, o => o.SumInternalCorrosionFailures);
var tmp = failures.Zip(lens, (x, y) => (x > 0 && y > 0 ? x / y : failures.Sum() / lens.Sum())).ToArray();
factors.InternalCoating[PrioritizationModelFactors.InternalCoatingCodes.cat1] = tmp[0];
factors.InternalCoating[PrioritizationModelFactors.InternalCoatingCodes.cat2] = tmp[1];
factors.InternalCoating[PrioritizationModelFactors.InternalCoatingCodes.cat3] = tmp[2];
factors.InternalCoating[PrioritizationModelFactors.InternalCoatingCodes.cat4] = tmp[3];
factors.InternalCoating[PrioritizationModelFactors.InternalCoatingCodes.cat5] = tmp[4];
factors.InternalCoating[PrioritizationModelFactors.InternalCoatingCodes.cat6] = tmp[5];
public static void FitPipeMaterial(PrioritizationModelFactors factors, PrioritizationData[] data)
var CurrentConds = new Func<PrioritizationData, bool>[] {
o => o.MaterialCode == 1 && o.CurrentAge >=0,
o => o.MaterialCode == 2 && o.CurrentAge >=0,
o => o.MaterialCode == 3 && o.CurrentAge >=0,
o => o.MaterialCode == 4 && o.CurrentAge >=0,
o => o.MaterialCode == 5 && o.CurrentAge >=0,
o => o.MaterialCode == 6 && o.CurrentAge >=0,
o => o.MaterialCode == 7 && o.CurrentAge >=0 };
var LastConds = new Func<PrioritizationData, bool>[] {
o => o.MaterialCode == 1 && o.LastAge >=0,
o => o.MaterialCode == 2 && o.LastAge >=0,
o => o.MaterialCode == 3 && o.LastAge >=0,
o => o.MaterialCode == 4 && o.LastAge >=0,
o => o.MaterialCode == 5 && o.LastAge >=0,
o => o.MaterialCode == 6 && o.LastAge >=0,
o => o.MaterialCode == 7 && o.LastAge >=0 };
var YearConds = new Func<PrioritizationData, bool>[] {
o => o.MaterialCode == 1 && o.YearAge >=0,
o => o.MaterialCode == 2 && o.YearAge >=0,
o => o.MaterialCode == 3 && o.YearAge >=0,
o => o.MaterialCode == 4 && o.YearAge >=0,
o => o.MaterialCode == 5 && o.YearAge >=0,
o => o.MaterialCode == 6 && o.YearAge >=0,
o => o.MaterialCode == 7 && o.YearAge >=0 };
var conds = new Func<PrioritizationData, bool>[] {
o => o.MaterialCode == 1,
o => o.MaterialCode == 2,
o => o.MaterialCode == 3,
o => o.MaterialCode == 4,
o => o.MaterialCode == 5,
o => o.MaterialCode == 6,
o => o.MaterialCode == 7 };
var lens = sum2(data, CurrentConds, o => o.Length).Zip(sum2(data, LastConds, o => o.Length), (x, y) => x + y).Zip(sum2(data, YearConds, o => o.Length), (x, y) => x + y);
var failures = sum2(data, conds, o => o.SumInternalCorrosionFailures);
var tmp = failures.Zip(lens, (x, y) => (x > 0 && y > 0 ? x / y : failures.Sum() / lens.Sum())).ToArray();
Func<int, int> fill = (code) => { factors.PipeMaterial[PipeMaterialCodes.FromMaterialCode(code)] = tmp[code - 1]; return code; };
Enumerable.Range(1, 7).Select(o => fill(o)).ToArray();
public static void FitPurposePipeline(PrioritizationModelFactors factors, PrioritizationData[] data)
var CurrentConds = new Func<PrioritizationData, bool>[] {
o => o.PurposePipelineCode == 1 && o.CurrentAge >=0,
o => o.PurposePipelineCode == 2 && o.CurrentAge >=0,
o => o.PurposePipelineCode == 3 && o.CurrentAge >=0,
o => o.PurposePipelineCode == 4 && o.CurrentAge >=0,
o => o.PurposePipelineCode == 5 && o.CurrentAge >=0,
o => o.PurposePipelineCode == 6 && o.CurrentAge >=0,
o => o.PurposePipelineCode == 7 && o.CurrentAge >=0,
o => o.PurposePipelineCode == 8 && o.CurrentAge >=0,
o => o.PurposePipelineCode == 9 && o.CurrentAge >=0 };
var LastConds = new Func<PrioritizationData, bool>[] {
o => o.PurposePipelineCode == 1 && o.LastAge >=0,
o => o.PurposePipelineCode == 2 && o.LastAge >=0,
o => o.PurposePipelineCode == 3 && o.LastAge >=0,
o => o.PurposePipelineCode == 4 && o.LastAge >=0,
o => o.PurposePipelineCode == 5 && o.LastAge >=0,
o => o.PurposePipelineCode == 6 && o.LastAge >=0,
o => o.PurposePipelineCode == 7 && o.LastAge >=0,
o => o.PurposePipelineCode == 8 && o.LastAge >=0,
o => o.PurposePipelineCode == 9 && o.LastAge >=0 };
var YearConds = new Func<PrioritizationData, bool>[] {
o => o.PurposePipelineCode == 1 && o.YearAge >=0,
o => o.PurposePipelineCode == 2 && o.YearAge >=0,
o => o.PurposePipelineCode == 3 && o.YearAge >=0,
o => o.PurposePipelineCode == 4 && o.YearAge >=0,
o => o.PurposePipelineCode == 5 && o.YearAge >=0,
o => o.PurposePipelineCode == 6 && o.YearAge >=0,
o => o.PurposePipelineCode == 7 && o.YearAge >=0,
o => o.PurposePipelineCode == 8 && o.YearAge >=0,
o => o.PurposePipelineCode == 9 && o.YearAge >=0 };
var conds = new Func<PrioritizationData, bool>[] {
o => o.PurposePipelineCode == 1,
o => o.PurposePipelineCode == 2,
o => o.PurposePipelineCode == 3,
o => o.PurposePipelineCode == 4,
o => o.PurposePipelineCode == 5,
o => o.PurposePipelineCode == 6,
o => o.PurposePipelineCode == 7,
o => o.PurposePipelineCode == 8,
o => o.PurposePipelineCode == 9 };
var lens = sum2(data, CurrentConds, o => o.Length).Zip(sum2(data, LastConds, o => o.Length), (x, y) => x + y).Zip(sum2(data, YearConds, o => o.Length), (x, y) => x + y);
var failures = sum2(data, conds, o => o.SumInternalCorrosionFailures);
var tmp = failures.Zip(lens, (x, y) => (x > 0 && y > 0 ? x / y : failures.Sum() / lens.Sum())).ToArray();
factors.PurposePipeline[PrioritizationModelFactors.PurposePipelineCodes.cat1] = tmp[0];
factors.PurposePipeline[PrioritizationModelFactors.PurposePipelineCodes.cat2] = tmp[1];
factors.PurposePipeline[PrioritizationModelFactors.PurposePipelineCodes.cat3] = tmp[2];
factors.PurposePipeline[PrioritizationModelFactors.PurposePipelineCodes.cat4] = tmp[3];
factors.PurposePipeline[PrioritizationModelFactors.PurposePipelineCodes.cat5] = tmp[4];
factors.PurposePipeline[PrioritizationModelFactors.PurposePipelineCodes.cat6] = tmp[5];
factors.PurposePipeline[PrioritizationModelFactors.PurposePipelineCodes.cat7] = tmp[6];
factors.PurposePipeline[PrioritizationModelFactors.PurposePipelineCodes.cat8] = tmp[7];
factors.PurposePipeline[PrioritizationModelFactors.PurposePipelineCodes.cat9] = tmp[8];
public static void FitInhibition(PrioritizationModelFactors factors, PrioritizationData[] data)
var CurrentConds = new Func<PrioritizationData, bool>[] {
o => o.IsInhibition && o.CurrentAge >=0,
o => !o.IsInhibition && o.CurrentAge >=0 };
var LastConds = new Func<PrioritizationData, bool>[] {
o => o.IsInhibition && o.LastAge >=0,
o => !o.IsInhibition && o.LastAge >=0 };
var YearConds = new Func<PrioritizationData, bool>[] {
o => o.IsInhibition && o.YearAge >=0,
o => !o.IsInhibition && o.YearAge >=0 };
var conds = new Func<PrioritizationData, bool>[] {
var lens = sum2(data, CurrentConds, o => o.Length).Zip(sum2(data, LastConds, o => o.Length), (x, y) => x + y).Zip(sum2(data, YearConds, o => o.Length), (x, y) => x + y);
var failures = sum2(data, conds, o => o.SumInternalCorrosionFailures);
var tmp = failures.Zip(lens, (x, y) => (x > 0 && y > 0 ? x / y : failures.Sum() / lens.Sum())).ToArray();
factors.Inhibition[PrioritizationModelFactors.InhibitionCodes.cat1] = tmp[0];
factors.Inhibition[PrioritizationModelFactors.InhibitionCodes.cat2] = tmp[1];
public static void FitCorrosionRate(PrioritizationModelFactors factors, PrioritizationData[] data)
var CurrentConds = new Func<PrioritizationData, bool>[] {
o => o.AvgCorrosionRate == CorrosionRateCode.no && o.CurrentAge >=0 && o.MaterialCode != 4,
o => o.AvgCorrosionRate == CorrosionRateCode.low && o.CurrentAge >=0 && o.MaterialCode != 4,
o => o.AvgCorrosionRate == CorrosionRateCode.avg && o.CurrentAge >=0 && o.MaterialCode != 4,
o => o.AvgCorrosionRate == CorrosionRateCode.high && o.CurrentAge >=0 && o.MaterialCode != 4,
o => o.AvgCorrosionRate == CorrosionRateCode.no_data && o.CurrentAge >=0 && o.MaterialCode != 4 };
var LastConds = new Func<PrioritizationData, bool>[] {
o => o.AvgCorrosionRate == CorrosionRateCode.no && o.LastAge >=0 && o.MaterialCode != 4,
o => o.AvgCorrosionRate == CorrosionRateCode.low && o.LastAge >=0 && o.MaterialCode != 4,
o => o.AvgCorrosionRate == CorrosionRateCode.avg && o.LastAge >=0 && o.MaterialCode != 4,
o => o.AvgCorrosionRate == CorrosionRateCode.high && o.LastAge >=0 && o.MaterialCode != 4,
o => o.AvgCorrosionRate == CorrosionRateCode.no_data && o.LastAge >=0 && o.MaterialCode != 4 };
var YearConds = new Func<PrioritizationData, bool>[] {
o => o.AvgCorrosionRate == CorrosionRateCode.no && o.YearAge >=0 && o.MaterialCode != 4,
o => o.AvgCorrosionRate == CorrosionRateCode.low && o.YearAge >=0 && o.MaterialCode != 4,
o => o.AvgCorrosionRate == CorrosionRateCode.avg && o.YearAge >=0 && o.MaterialCode != 4,
o => o.AvgCorrosionRate == CorrosionRateCode.high && o.YearAge >=0 && o.MaterialCode != 4,
o => o.AvgCorrosionRate == CorrosionRateCode.no_data && o.YearAge >=0 && o.MaterialCode != 4 };
var conds = new Func<PrioritizationData, bool>[] {
o => o.AvgCorrosionRate == CorrosionRateCode.no && o.MaterialCode != 4,
o => o.AvgCorrosionRate == CorrosionRateCode.low && o.MaterialCode != 4,
o => o.AvgCorrosionRate == CorrosionRateCode.avg && o.MaterialCode != 4,
o => o.AvgCorrosionRate == CorrosionRateCode.high && o.MaterialCode != 4,
o => o.AvgCorrosionRate == CorrosionRateCode.no_data && o.MaterialCode != 4 };
var lens = sum2(data, CurrentConds, o => o.Length).Zip(sum2(data, LastConds, o => o.Length), (x, y) => x + y).Zip(sum2(data, YearConds, o => o.Length), (x, y) => x + y);
var failures = sum2(data, conds, o => o.SumInternalCorrosionFailures);
var tmp = failures.Zip(lens, (x, y) => (x > 0 && y > 0 ? x / y : failures.Sum() / lens.Sum())).ToArray();
factors.CorrosionRate[PrioritizationModelFactors.CorrosionRateCodes.cat1] = tmp[0];
factors.CorrosionRate[PrioritizationModelFactors.CorrosionRateCodes.cat2] = tmp[1];
factors.CorrosionRate[PrioritizationModelFactors.CorrosionRateCodes.cat3] = tmp[2];
factors.CorrosionRate[PrioritizationModelFactors.CorrosionRateCodes.cat4] = tmp[3];
factors.CorrosionRate[PrioritizationModelFactors.CorrosionRateCodes.cat5] = tmp[4];
public static void FitH2S(PrioritizationModelFactors factors, PrioritizationData[] data)
var CurrentConds = new Func<PrioritizationData, bool>[] {
o => o.H2S == H2SCode.no && o.CurrentAge >=0,
o => o.H2S == H2SCode.low && o.CurrentAge >=0,
o => o.H2S == H2SCode.avg && o.CurrentAge >=0,
o => o.H2S == H2SCode.high && o.CurrentAge >=0,
o => o.H2S == H2SCode.no_data && o.CurrentAge >=0 };
var LastConds = new Func<PrioritizationData, bool>[] {
o => o.H2S == H2SCode.no && o.LastAge >=0,
o => o.H2S == H2SCode.low && o.LastAge >=0,
o => o.H2S == H2SCode.avg && o.LastAge >=0,
o => o.H2S == H2SCode.high && o.LastAge >=0,
o => o.H2S == H2SCode.no_data && o.LastAge >=0 };
var YearConds = new Func<PrioritizationData, bool>[] {
o => o.H2S == H2SCode.no && o.YearAge >=0,
o => o.H2S == H2SCode.low && o.YearAge >=0,
o => o.H2S == H2SCode.avg && o.YearAge >=0,
o => o.H2S == H2SCode.high && o.YearAge >=0,
o => o.H2S == H2SCode.no_data && o.YearAge >=0 };
var conds = new Func<PrioritizationData, bool>[] {
o => o.H2S == H2SCode.no,
o => o.H2S == H2SCode.low,
o => o.H2S == H2SCode.avg,
o => o.H2S == H2SCode.high,
o => o.H2S == H2SCode.no_data };
var lens = sum2(data, CurrentConds, o => o.Length).Zip(sum2(data, LastConds, o => o.Length), (x, y) => x + y).Zip(sum2(data, YearConds, o => o.Length), (x, y) => x + y);
var failures = sum2(data, conds, o => o.SumInternalCorrosionFailures);
var tmp = failures.Zip(lens, (x, y) => (x > 0 && y > 0 ? x / y : failures.Sum() / lens.Sum())).ToArray();
factors.H2S[PrioritizationModelFactors.H2SCodes.cat1] = tmp[0];
factors.H2S[PrioritizationModelFactors.H2SCodes.cat2] = tmp[1];
factors.H2S[PrioritizationModelFactors.H2SCodes.cat3] = tmp[2];
factors.H2S[PrioritizationModelFactors.H2SCodes.cat4] = tmp[3];
factors.H2S[PrioritizationModelFactors.H2SCodes.cat5] = tmp[4];
public static void FitSoilCorrosivity(PrioritizationModelFactors factors, PrioritizationData[] data)
var CurrentConds = new Func<PrioritizationData, bool>[] {
o => o.Soil == SoilCorrosivityCode.low && o.CurrentAge >=0,
o => o.Soil == SoilCorrosivityCode.avg && o.CurrentAge >=0,
o => o.Soil == SoilCorrosivityCode.high && o.CurrentAge >=0,
o => o.Soil == SoilCorrosivityCode.no_data && o.CurrentAge >=0 };
var LastConds = new Func<PrioritizationData, bool>[] {
o => o.Soil == SoilCorrosivityCode.low && o.LastAge >=0,
o => o.Soil == SoilCorrosivityCode.avg && o.LastAge >=0,
o => o.Soil == SoilCorrosivityCode.high && o.LastAge >=0,
o => o.Soil == SoilCorrosivityCode.no_data && o.LastAge >=0 };
var YearConds = new Func<PrioritizationData, bool>[] {
o => o.Soil == SoilCorrosivityCode.low && o.YearAge >=0,
o => o.Soil == SoilCorrosivityCode.avg && o.YearAge >=0,
o => o.Soil == SoilCorrosivityCode.high && o.YearAge >=0,
o => o.Soil == SoilCorrosivityCode.no_data && o.YearAge >=0 };
var conds = new Func<PrioritizationData, bool>[] {
o => o.Soil == SoilCorrosivityCode.low,
o => o.Soil == SoilCorrosivityCode.avg,
o => o.Soil == SoilCorrosivityCode.high,
o => o.Soil == SoilCorrosivityCode.no_data };
var lens = sum2(data, CurrentConds, o => o.Length).Zip(sum2(data, LastConds, o => o.Length), (x, y) => x + y).Zip(sum2(data, YearConds, o => o.Length), (x, y) => x + y);
var failures = sum2(data, conds, o => o.SumOuterCorrosionFailures);
var tmp = failures.Zip(lens, (x, y) => (x > 0 && y > 0 ? x / y : failures.Sum() / lens.Sum())).ToArray();
factors.SoilCorrosivity[PrioritizationModelFactors.SoilCorrosivityCodes.cat1] = tmp[0];
factors.SoilCorrosivity[PrioritizationModelFactors.SoilCorrosivityCodes.cat2] = tmp[1];
factors.SoilCorrosivity[PrioritizationModelFactors.SoilCorrosivityCodes.cat3] = tmp[2];
factors.SoilCorrosivity[PrioritizationModelFactors.SoilCorrosivityCodes.cat4] = tmp[3];
public static void FitCurrents(PrioritizationModelFactors factors, PrioritizationData[] data)
var CurrentConds = new Func<PrioritizationData, bool>[] {
o => o.StrayCurrents.HasValue && !o.StrayCurrents.Value && o.CurrentAge >=0,
o => o.StrayCurrents.HasValue && o.StrayCurrents.Value && o.CurrentAge >=0,
o => !o.StrayCurrents.HasValue && o.CurrentAge >=0 };
var LastConds = new Func<PrioritizationData, bool>[] {
o => o.StrayCurrents.HasValue && !o.StrayCurrents.Value && o.LastAge >=0,
o => o.StrayCurrents.HasValue && o.StrayCurrents.Value && o.LastAge >=0,
o => !o.StrayCurrents.HasValue && o.LastAge >=0 };
var YearConds = new Func<PrioritizationData, bool>[] {
o => o.StrayCurrents.HasValue && !o.StrayCurrents.Value && o.YearAge >=0,
o => o.StrayCurrents.HasValue && o.StrayCurrents.Value && o.YearAge >=0,
o => !o.StrayCurrents.HasValue && o.YearAge >=0 };
var conds = new Func<PrioritizationData, bool>[] {
o => o.StrayCurrents.HasValue && !o.StrayCurrents.Value,
o => o.StrayCurrents.HasValue && o.StrayCurrents.Value,
o => !o.StrayCurrents.HasValue };
var lens = sum2(data, CurrentConds, o => o.Length).Zip(sum2(data, LastConds, o => o.Length), (x, y) => x + y).Zip(sum2(data, YearConds, o => o.Length), (x, y) => x + y);
var failures = sum2(data, conds, o => o.SumOuterCorrosionFailures);
var tmp = failures.Zip(lens, (x, y) => (x > 0 && y > 0 ? x / y : failures.Sum() / lens.Sum())).ToArray();
factors.Currents[PrioritizationModelFactors.CurrentsCodes.cat1] = tmp[0];
factors.Currents[PrioritizationModelFactors.CurrentsCodes.cat2] = tmp[1];
factors.Currents[PrioritizationModelFactors.CurrentsCodes.cat3] = tmp[2];
public static void FitOuterCoating(PrioritizationModelFactors factors, PrioritizationData[] data)
var CurrentConds = new Func<PrioritizationData, bool>[] {
o => o.OuterCoatingOrICCP == OuterCoatingOrICCPCode.no && o.CurrentAge >=0,
o => o.OuterCoatingOrICCP == OuterCoatingOrICCPCode.coating && o.CurrentAge >=0,
o => o.OuterCoatingOrICCP == OuterCoatingOrICCPCode.ICCP && o.CurrentAge >=0,
o => o.OuterCoatingOrICCP == OuterCoatingOrICCPCode.coating_ICCP && o.CurrentAge >=0 };
var LastConds = new Func<PrioritizationData, bool>[] {
o => o.OuterCoatingOrICCP == OuterCoatingOrICCPCode.no && o.LastAge >=0,
o => o.OuterCoatingOrICCP == OuterCoatingOrICCPCode.coating && o.LastAge >=0,
o => o.OuterCoatingOrICCP == OuterCoatingOrICCPCode.ICCP && o.LastAge >=0,
o => o.OuterCoatingOrICCP == OuterCoatingOrICCPCode.coating_ICCP && o.LastAge >=0 };
var YearConds = new Func<PrioritizationData, bool>[] {
o => o.OuterCoatingOrICCP == OuterCoatingOrICCPCode.no && o.YearAge >=0,
o => o.OuterCoatingOrICCP == OuterCoatingOrICCPCode.coating && o.YearAge >=0,
o => o.OuterCoatingOrICCP == OuterCoatingOrICCPCode.ICCP && o.YearAge >=0,
o => o.OuterCoatingOrICCP == OuterCoatingOrICCPCode.coating_ICCP && o.YearAge >=0 };
var conds = new Func<PrioritizationData, bool>[] {
o => o.OuterCoatingOrICCP == OuterCoatingOrICCPCode.no,
o => o.OuterCoatingOrICCP == OuterCoatingOrICCPCode.coating,
o => o.OuterCoatingOrICCP == OuterCoatingOrICCPCode.ICCP,
o => o.OuterCoatingOrICCP == OuterCoatingOrICCPCode.coating_ICCP };
var lens = sum2(data, CurrentConds, o => o.Length).Zip(sum2(data, LastConds, o => o.Length), (x, y) => x + y).Zip(sum2(data, YearConds, o => o.Length), (x, y) => x + y);
var failures = sum2(data, conds, o => o.SumOuterCorrosionFailures);
var tmp = failures.Zip(lens, (x, y) => (x > 0 && y > 0 ? x / y : failures.Sum() / lens.Sum())).ToArray();
factors.OuterCoating[PrioritizationModelFactors.OuterCoatingCodes.cat1] = tmp[0];
factors.OuterCoating[PrioritizationModelFactors.OuterCoatingCodes.cat2] = tmp[1];
factors.OuterCoating[PrioritizationModelFactors.OuterCoatingCodes.cat3] = tmp[2];
factors.OuterCoating[PrioritizationModelFactors.OuterCoatingCodes.cat4] = tmp[3];
public static void FitInspection(PrioritizationModelFactors factors, PrioritizationData[] data)
var YearConds = new Func<PrioritizationData, bool>[] {
o => o.Diagnoctic == DiagnocticCode.no && o.YearAge >=0,
o => o.Diagnoctic == DiagnocticCode.ser && o.YearAge >=0,
o => o.Diagnoctic == DiagnocticCode.ae && o.YearAge >=0,
o => o.Diagnoctic == DiagnocticCode.ili && o.YearAge >=0,
o => o.Diagnoctic == DiagnocticCode.hi && o.YearAge >=0,
o => o.Diagnoctic == DiagnocticCode.si && o.YearAge >=0,
o => o.Diagnoctic == DiagnocticCode.ud && o.YearAge >=0 };
var conds = new Func<PrioritizationData, bool>[] {
o => o.Diagnoctic == DiagnocticCode.no,
o => o.Diagnoctic == DiagnocticCode.ser,
o => o.Diagnoctic == DiagnocticCode.ae,
o => o.Diagnoctic == DiagnocticCode.ili,
o => o.Diagnoctic == DiagnocticCode.hi,
o => o.Diagnoctic == DiagnocticCode.si,
o => o.Diagnoctic == DiagnocticCode.ud };
var lens = sum2(data, YearConds, o => o.Length);
var failures = sum2(data, conds, o => o.SumInternalCorrosionFailures);
var tmp = failures.Zip(lens, (x, y) => (x > 0 && y > 0 ? x / y : failures.Sum() / lens.Sum())).ToArray();
factors.Inspection[PrioritizationModelFactors.InspectionCodes.cat1] = tmp[0];
factors.Inspection[PrioritizationModelFactors.InspectionCodes.cat2] = tmp[1];
factors.Inspection[PrioritizationModelFactors.InspectionCodes.cat3] = tmp[2];
factors.Inspection[PrioritizationModelFactors.InspectionCodes.cat4] = tmp[3];
factors.Inspection[PrioritizationModelFactors.InspectionCodes.cat5] = tmp[4];
factors.Inspection[PrioritizationModelFactors.InspectionCodes.cat6] = tmp[5];
factors.Inspection[PrioritizationModelFactors.InspectionCodes.cat7] = tmp[6];
public static void FitPigging(PrioritizationModelFactors factors, PrioritizationData[] data)
var CurrentConds = new Func<PrioritizationData, bool>[] {
o => o.IsPigging && o.CurrentAge >=0,
o => !o.IsPigging && o.CurrentAge >=0 };
var LastConds = new Func<PrioritizationData, bool>[] {
o => o.IsPigging && o.LastAge >=0,
o => !o.IsPigging && o.LastAge >=0 };
var YearConds = new Func<PrioritizationData, bool>[] {
o => o.IsPigging && o.YearAge >=0,
o => !o.IsPigging && o.YearAge >=0 };
var conds = new Func<PrioritizationData, bool>[] {
var lens = sum2(data, CurrentConds, o => o.Length).Zip(sum2(data, LastConds, o => o.Length), (x, y) => x + y).Zip(sum2(data, YearConds, o => o.Length), (x, y) => x + y);
var failures = sum2(data, conds, o => o.SumInternalCorrosionFailures);
var tmp = failures.Zip(lens, (x, y) => (x > 0 && y > 0 ? x / y : failures.Sum() / lens.Sum())).ToArray();
factors.Pigging[PrioritizationModelFactors.PiggingCodes.cat1] = tmp[0];
factors.Pigging[PrioritizationModelFactors.PiggingCodes.cat2] = tmp[1];
public static void FitWaterCut(PrioritizationModelFactors factors, PrioritizationData[] data)
var CurrentConds = new Func<PrioritizationData, bool>[] {
o => o.WaterCut == WaterCutCode.low && o.CurrentAge >=0,
o => o.WaterCut == WaterCutCode.high && o.CurrentAge >=0,
o => o.WaterCut == WaterCutCode.mono && o.CurrentAge >=0 };
var LastConds = new Func<PrioritizationData, bool>[] {
o => o.WaterCut == WaterCutCode.low && o.LastAge >=0,
o => o.WaterCut == WaterCutCode.high && o.LastAge >=0,
o => o.WaterCut == WaterCutCode.mono && o.LastAge >=0};
var YearConds = new Func<PrioritizationData, bool>[] {
o => o.WaterCut == WaterCutCode.low && o.YearAge >=0,
o => o.WaterCut == WaterCutCode.high && o.YearAge >=0,
o => o.WaterCut == WaterCutCode.mono && o.YearAge >=0 };
var conds = new Func<PrioritizationData, bool>[] {
o => o.WaterCut == WaterCutCode.low,
o => o.WaterCut == WaterCutCode.high,
o => o.WaterCut == WaterCutCode.mono };
var lens = sum2(data, CurrentConds, o => o.Length).Zip(sum2(data, LastConds, o => o.Length), (x, y) => x + y).Zip(sum2(data, YearConds, o => o.Length), (x, y) => x + y);
var failures = sum2(data, conds, o => o.SumInternalCorrosionFailures);
var tmp = failures.Zip(lens, (x, y) => (x > 0 && y > 0 ? x / y : failures.Sum() / lens.Sum())).ToArray();
factors.WaterCut[PrioritizationModelFactors.WaterCutCodes.cat1] = tmp[0];
factors.WaterCut[PrioritizationModelFactors.WaterCutCodes.cat2] = tmp[1];
factors.WaterCut[PrioritizationModelFactors.WaterCutCodes.cat3] = tmp[2];
public static void FitFluidVelocity(PrioritizationModelFactors factors, PrioritizationData[] data)
var CurrentConds = new Func<PrioritizationData, bool>[] {
o => o.FluidVelocity == FluidVelocityCode.water_low && o.CurrentAge >=0,
o => o.FluidVelocity == FluidVelocityCode.water_high && o.CurrentAge >=0,
o => o.FluidVelocity == FluidVelocityCode.oil_water_low && o.CurrentAge >=0,
o => o.FluidVelocity == FluidVelocityCode.oil_water_medium && o.CurrentAge >=0,
o => o.FluidVelocity == FluidVelocityCode.oil_water_high && o.CurrentAge >=0,
o => o.FluidVelocity == FluidVelocityCode.water_oil_low && o.CurrentAge >=0,
o => o.FluidVelocity == FluidVelocityCode.water_oil_medium && o.CurrentAge >=0,
o => o.FluidVelocity == FluidVelocityCode.water_oil_high && o.CurrentAge >=0,
o => o.FluidVelocity == FluidVelocityCode.other && o.CurrentAge >=0 };
var LastConds = new Func<PrioritizationData, bool>[] {
o => o.FluidVelocity == FluidVelocityCode.water_low && o.LastAge >=0,
o => o.FluidVelocity == FluidVelocityCode.water_high && o.LastAge >=0,
o => o.FluidVelocity == FluidVelocityCode.oil_water_low && o.LastAge >=0,
o => o.FluidVelocity == FluidVelocityCode.oil_water_medium && o.LastAge >=0,
o => o.FluidVelocity == FluidVelocityCode.oil_water_high && o.LastAge >=0,
o => o.FluidVelocity == FluidVelocityCode.water_oil_low && o.LastAge >=0,
o => o.FluidVelocity == FluidVelocityCode.water_oil_medium && o.LastAge >=0,
o => o.FluidVelocity == FluidVelocityCode.water_oil_high && o.LastAge >=0,
o => o.FluidVelocity == FluidVelocityCode.other && o.LastAge >=0 };
var YearConds = new Func<PrioritizationData, bool>[] {
o => o.FluidVelocity == FluidVelocityCode.water_low && o.YearAge >=0,
o => o.FluidVelocity == FluidVelocityCode.water_high && o.YearAge >=0,
o => o.FluidVelocity == FluidVelocityCode.oil_water_low && o.YearAge >=0,
o => o.FluidVelocity == FluidVelocityCode.oil_water_medium && o.YearAge >=0,
o => o.FluidVelocity == FluidVelocityCode.oil_water_high && o.YearAge >=0,
o => o.FluidVelocity == FluidVelocityCode.water_oil_low && o.YearAge >=0,
o => o.FluidVelocity == FluidVelocityCode.water_oil_medium && o.YearAge >=0,
o => o.FluidVelocity == FluidVelocityCode.water_oil_high && o.YearAge >=0,
o => o.FluidVelocity == FluidVelocityCode.other && o.YearAge >=0 };
var conds = new Func<PrioritizationData, bool>[] {
o => o.FluidVelocity == FluidVelocityCode.water_low,
o => o.FluidVelocity == FluidVelocityCode.water_high,
o => o.FluidVelocity == FluidVelocityCode.oil_water_low,
o => o.FluidVelocity == FluidVelocityCode.oil_water_medium,
o => o.FluidVelocity == FluidVelocityCode.oil_water_high,
o => o.FluidVelocity == FluidVelocityCode.water_oil_low,
o => o.FluidVelocity == FluidVelocityCode.water_oil_medium,
o => o.FluidVelocity == FluidVelocityCode.water_oil_high,
o => o.FluidVelocity == FluidVelocityCode.other };
var lens = sum2(data, CurrentConds, o => o.Length).Zip(sum2(data, LastConds, o => o.Length), (x, y) => x + y).Zip(sum2(data, YearConds, o => o.Length), (x, y) => x + y);
var failures = sum2(data, conds, o => o.SumInternalCorrosionFailures);
var tmp = failures.Zip(lens, (x, y) => (x > 0 && y > 0 ? x / y : failures.Sum() / lens.Sum())).ToArray();
factors.FluidVelocity[PrioritizationModelFactors.FluidVelocityCodes.cat1] = tmp[0];
factors.FluidVelocity[PrioritizationModelFactors.FluidVelocityCodes.cat2] = tmp[1];
factors.FluidVelocity[PrioritizationModelFactors.FluidVelocityCodes.cat3] = tmp[2];
factors.FluidVelocity[PrioritizationModelFactors.FluidVelocityCodes.cat4] = tmp[3];
factors.FluidVelocity[PrioritizationModelFactors.FluidVelocityCodes.cat5] = tmp[4];
factors.FluidVelocity[PrioritizationModelFactors.FluidVelocityCodes.cat6] = tmp[5];
factors.FluidVelocity[PrioritizationModelFactors.FluidVelocityCodes.cat7] = tmp[6];
factors.FluidVelocity[PrioritizationModelFactors.FluidVelocityCodes.cat8] = tmp[7];
factors.FluidVelocity[PrioritizationModelFactors.FluidVelocityCodes.cat9] = tmp[8];
public static void Normilize<T>(Dictionary<T, float> dict, float val)
foreach (var key in dict.Keys.ToList())
#region Критический возраст
public static float[] CalcSpecificAccidentRate(PrioritizationData[] data, string purpose)
var years = Enumerable.Range(0, 51);
var CurrentConds = years.Select(y => new Func<PrioritizationData, bool>(o => o.PurposePipeline == purpose && o.CurrentAge == y)).ToArray();
var LastConds = years.Select(y => new Func<PrioritizationData, bool>(o => o.PurposePipeline == purpose && o.LastAge == y)).ToArray();
var YearConds = years.Select(y => new Func<PrioritizationData, bool>(o => o.PurposePipeline == purpose && o.YearAge == y)).ToArray();
var lens = sum2(data, CurrentConds, o => o.Length)
.Zip(sum2(data, LastConds, o => o.Length), (x, y) => x + y)
.Zip(sum2(data, YearConds, o => o.Length), (x, y) => x + y);
var failures = sum2(data, CurrentConds, o => o.CurrentInternalCorrosionFailures + o.CurrentOuterCorrosionFailures)
.Zip(sum2(data, LastConds, o => o.LastInternalCorrosionFailures + o.LastOuterCorrosionFailures), (x, y) => x + y)
.Zip(sum2(data, YearConds, o => o.YearInternalCorrosionFailures + o.YearOuterCorrosionFailures), (x, y) => x + y);
var SpecificAccidentRate = failures.Zip(lens, (x, y) => (x > 0 && y > 0 ? x / y : 0));
return SpecificAccidentRate.ToArray();
public static float[] AverageOverGroups(float[] data)
group element by i++ / 3 into splitGroups
select splitGroups.Average()
public static float[] OverallAverageOverGroups(float[][] DataSet)
var GroupedData = new List<List<float>>();
foreach (var data in DataSet)
.Select(grp => grp.ToList())
if (GroupedData.Count > 0)
for (int j = 0; j < groups.Count(); j++)
GroupedData[j].AddRange(groups[j]);
else GroupedData.AddRange(groups);
return GroupedData.Select(o => o.Average()).ToArray();
public static float[] Filter(float[] data, int minIdx, int maxIdx)
return data.Select((o, index) => (index >= minIdx - 1 && index <= maxIdx - 1) ? o : 0).ToArray();
public static int CalcCriticalAge(float[] OverallSpecificAccidentRate)
return OverallSpecificAccidentRate.MaxIndex() * 3 - 1 - 1;
public static int CountPositiveItem(float[] data)
return data.Count(o => o > 0);
public static void FitCriticalAge(PrioritizationModelFactors factors, PrioritizationData[] data)
var Purposes = typeof(PrioritizationModelFactors.PurposePipelineCodes).GetFields();
var PurposeNames = Purposes.Select(o => string.Concat(o.GetValue(null))).ToArray();
var SpecificAccidentRatesByPurpose = PurposeNames.Select(o => CalcSpecificAccidentRate(data, o)).ToArray();
var OverallCrticalAge = CalcCriticalAge(Filter(OverallAverageOverGroups(SpecificAccidentRatesByPurpose), 3, 9));
var GroupFiltersByPuprope = new ValueTuple<int, int>[] { (3, 9), (3, 9), (3, 9), (3, 9), (3, 9), (3, 7), (3, 9), (3, 9), (3, 9) };
var AverageGroupedSpecificAccidentRateByPurpose = GroupFiltersByPuprope.
Select((o, index) => AverageOverGroups(SpecificAccidentRatesByPurpose[index])).ToArray();
var FiltredAverageGroupedSpecificAccidentRateByPurpose = GroupFiltersByPuprope.
Select((o, index) => Filter(AverageGroupedSpecificAccidentRateByPurpose[index], o.Item1, o.Item2));
var PurposeCrticalAges = FiltredAverageGroupedSpecificAccidentRateByPurpose.Select(o => CalcCriticalAge(o));
var TestByPuprope = GroupFiltersByPuprope.Select((o, index) => CountPositiveItem(AverageGroupedSpecificAccidentRateByPurpose[index]) > 5).ToArray();
var CorrectedPurposeCrticalAges = PurposeCrticalAges.Select((o, index) => TestByPuprope[index] ? o : OverallCrticalAge);
factors.CriticalAge = PurposeNames.Zip(CorrectedPurposeCrticalAges, (p, a) => new { p, a })
.ToDictionary(item => item.p, item => item.a);
public PrioritizationModelFactors Fit(PrioritizationData[] data)
var factors = new PrioritizationModelFactors();
Fitting.FitLastYearFailure(factors, data);
Fitting.FitAllYearFailure(factors, data);
Fitting.FitFailureProbability(factors, data);
Fitting.FitInternalCoating(factors, data);
Fitting.FitPipeMaterial(factors, data);
Fitting.FitPurposePipeline(factors, data);
Fitting.FitInhibition(factors, data);
Fitting.FitCorrosionRate(factors, data);
Fitting.FitH2S(factors, data);
Fitting.FitSoilCorrosivity(factors, data);
Fitting.FitCurrents(factors, data);
Fitting.FitOuterCoating(factors, data);
Fitting.FitFluidVelocity(factors, data);
Fitting.FitWaterCut(factors, data);
Fitting.FitInspection(factors, data);
Fitting.FitPigging(factors, data);
var max = factors.BaseFactor;
Fitting.Normilize(factors.AllFailure, max);
Fitting.Normilize(factors.FailureProbability, max);
Fitting.Normilize(factors.InternalCoating, max);
Fitting.Normilize(factors.PipeMaterial, max);
Fitting.Normilize(factors.PurposePipeline, max);
Fitting.Normilize(factors.Inhibition, max);
Fitting.Normilize(factors.CorrosionRate, max);
Fitting.Normilize(factors.H2S, max);
Fitting.Normilize(factors.SoilCorrosivity, max);
Fitting.Normilize(factors.Currents, max);
Fitting.Normilize(factors.OuterCoating, max);
Fitting.Normilize(factors.WaterCut, max);
Fitting.Normilize(factors.FluidVelocity, max);
Fitting.Normilize(factors.Pigging, max);
Fitting.FitCriticalAge(factors, data);
public static void Main()
var data = new PrioritizationFileData[28];
data[0] = new PrioritizationFileData() { PurposePipelineName = "Вык. лин. одиночных скв.", Length = 10.864f, CommissioningYear = 1978, Diameter = 114, Thickness = 5, MaterialName = "Ст.20", InternalCoating = "Нет покрытия", Inhibition = "Да", OuterCoatingOrICCP = "Без покрытия и ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = 0.0098f, H2S = "Отсутствует ", Soil = "Среднее", StrayCurrents = "да", DefectNum = null, CurrentInternalCorrosionFailures = 19, CurrentOuterCorrosionFailures = 0, LastInternalCorrosionFailures = 1, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 1, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 19, AllOuterCorrosionFailures = 0, Pin = null, Pout = null, Qliq = null, Qgas = null, Qoil = null, WaterCut = null };
data[1] = new PrioritizationFileData() { PurposePipelineName = "Напорные нефтепроводы", Length = 2f, CommissioningYear = 1980, Diameter = 120, Thickness = 6, MaterialName = "Ст.21", InternalCoating = "Секции стальных труб, футерованных полиэтиленом (СФП)", Inhibition = "Да", OuterCoatingOrICCP = "с защитным покрытием без защиты ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = 0f, H2S = "Отсутствует ", Soil = "Среднее", StrayCurrents = "да", DefectNum = null, CurrentInternalCorrosionFailures = 18, CurrentOuterCorrosionFailures = 0, LastInternalCorrosionFailures = 1, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 1, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 18, AllOuterCorrosionFailures = 0, Pin = 25f, Pout = 8f, Qliq = 200f, Qgas = 300f, Qoil = 100f, WaterCut = 5f };
data[2] = new PrioritizationFileData() { PurposePipelineName = "Нефтесборные сети", Length = 10.864f, CommissioningYear = 1982, Diameter = 132, Thickness = 7, MaterialName = "Ст.20", InternalCoating = "Нет покрытия", Inhibition = "Да", OuterCoatingOrICCP = "Без покрытия и ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = 0.0098f, H2S = "Низкое", Soil = "Среднее", StrayCurrents = "Да", DefectNum = null, CurrentInternalCorrosionFailures = 17, CurrentOuterCorrosionFailures = 0, LastInternalCorrosionFailures = 5, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 1, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 17, AllOuterCorrosionFailures = 0, Pin = 25f, Pout = 8f, Qliq = 744f, Qgas = null, Qoil = null, WaterCut = 26.2f };
data[3] = new PrioritizationFileData() { PurposePipelineName = "Водовод низк. давл. пресной воды", Length = 3f, CommissioningYear = 1984, Diameter = 160, Thickness = 8, MaterialName = "13ХФА", InternalCoating = "Нет покрытия", Inhibition = "Да", OuterCoatingOrICCP = "с защитным покрытием без защиты ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = null, H2S = "Низкое", Soil = "Среднее", StrayCurrents = "да", DefectNum = null, CurrentInternalCorrosionFailures = 16, CurrentOuterCorrosionFailures = 0, LastInternalCorrosionFailures = 3, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 1, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 16, AllOuterCorrosionFailures = 0, Pin = 25f, Pout = 8f, Qliq = 744f, Qgas = null, Qoil = 474f, WaterCut = null };
data[4] = new PrioritizationFileData() { PurposePipelineName = "Вык. лин. одиночных скв.", Length = 10.864f, CommissioningYear = 1986, Diameter = 219, Thickness = 9, MaterialName = "Ст.20", InternalCoating = "Нет покрытия", Inhibition = "Да", OuterCoatingOrICCP = "Без покрытия и ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = 0.0098f, H2S = "Высокое", Soil = "Высокое", StrayCurrents = "да", DefectNum = null, CurrentInternalCorrosionFailures = 15, CurrentOuterCorrosionFailures = 0, LastInternalCorrosionFailures = 4, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 1, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 15, AllOuterCorrosionFailures = 0, Pin = 25f, Pout = 8f, Qliq = null, Qgas = null, Qoil = 474f, WaterCut = 26.2f };
data[5] = new PrioritizationFileData() { PurposePipelineName = "Напорные нефтепроводы", Length = 1f, CommissioningYear = 1988, Diameter = 250, Thickness = 10, MaterialName = "Ст.21", InternalCoating = "Нет покрытия", Inhibition = "Да", OuterCoatingOrICCP = "с защитным покрытием без защиты ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = 0.0098f, H2S = "Высокое", Soil = "Среднее", StrayCurrents = "да", DefectNum = null, CurrentInternalCorrosionFailures = 14, CurrentOuterCorrosionFailures = 0, LastInternalCorrosionFailures = 1, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 1, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 14, AllOuterCorrosionFailures = 0, Pin = 25f, Pout = 8f, Qliq = 744f, Qgas = null, Qoil = 474f, WaterCut = 26.2f };
data[6] = new PrioritizationFileData() { PurposePipelineName = "Нефтесборные сети", Length = 10.864f, CommissioningYear = 1990, Diameter = 300, Thickness = 12, MaterialName = "Ст.20", InternalCoating = "Нет покрытия", Inhibition = "Да", OuterCoatingOrICCP = "Без покрытия и ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = null, H2S = "Нет данных", Soil = "Среднее", StrayCurrents = "Нет", DefectNum = null, CurrentInternalCorrosionFailures = 13, CurrentOuterCorrosionFailures = 0, LastInternalCorrosionFailures = 1, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 1, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 13, AllOuterCorrosionFailures = 0, Pin = 25f, Pout = 8f, Qliq = 744f, Qgas = null, Qoil = 474f, WaterCut = 70f };
data[7] = new PrioritizationFileData() { PurposePipelineName = "Напорные нефтепроводы", Length = 6f, CommissioningYear = 1992, Diameter = 325, Thickness = 5, MaterialName = "Ст.21", InternalCoating = "Нет покрытия", Inhibition = "Да", OuterCoatingOrICCP = "с защитным покрытием без защиты ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = 0.0098f, H2S = "Нет данных", Soil = "Высокое", StrayCurrents = "да", DefectNum = null, CurrentInternalCorrosionFailures = 12, CurrentOuterCorrosionFailures = 0, LastInternalCorrosionFailures = 1, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 1, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 12, AllOuterCorrosionFailures = 0, Pin = 25f, Pout = 8f, Qliq = 744f, Qgas = null, Qoil = 474f, WaterCut = null };
data[8] = new PrioritizationFileData() { PurposePipelineName = "Нефтепровод внешнего транспорта", Length = 10.864f, CommissioningYear = 1994, Diameter = 350, Thickness = 6, MaterialName = "Ст.20", InternalCoating = "Нет покрытия", Inhibition = "Да", OuterCoatingOrICCP = "Без покрытия и ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = 0.0098f, H2S = "среднее", Soil = "Среднее", StrayCurrents = "да", DefectNum = null, CurrentInternalCorrosionFailures = 11, CurrentOuterCorrosionFailures = 0, LastInternalCorrosionFailures = 1, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 1, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 11, AllOuterCorrosionFailures = 0, Pin = 25f, Pout = 8f, Qliq = 744f, Qgas = null, Qoil = 474f, WaterCut = 26.2f };
data[9] = new PrioritizationFileData() { PurposePipelineName = "Напорные нефтепроводы", Length = 1.244f, CommissioningYear = 1996, Diameter = 426, Thickness = 7, MaterialName = "Ст.21", InternalCoating = "Нет покрытия", Inhibition = "Да", OuterCoatingOrICCP = "с защитным покрытием без защиты ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = 0.0098f, H2S = "среднее", Soil = "Среднее", StrayCurrents = "да", DefectNum = null, CurrentInternalCorrosionFailures = 10, CurrentOuterCorrosionFailures = 0, LastInternalCorrosionFailures = 1, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 1, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 10, AllOuterCorrosionFailures = 0, Pin = 25f, Pout = 8f, Qliq = 744f, Qgas = null, Qoil = 474f, WaterCut = 26.2f };
data[10] = new PrioritizationFileData() { PurposePipelineName = "Нефтепровод внешнего транспорта", Length = 10.864f, CommissioningYear = 1998, Diameter = 500, Thickness = 8, MaterialName = "Ст.20", InternalCoating = "Нет покрытия", Inhibition = "Да", OuterCoatingOrICCP = "Без покрытия и ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = 1f, H2S = "среднее", Soil = "Среднее", StrayCurrents = "Нет данных", DefectNum = null, CurrentInternalCorrosionFailures = 9, CurrentOuterCorrosionFailures = 0, LastInternalCorrosionFailures = 1, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 1, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 9, AllOuterCorrosionFailures = 0, Pin = 25f, Pout = 8f, Qliq = 744f, Qgas = null, Qoil = 474f, WaterCut = 26.2f };
data[11] = new PrioritizationFileData() { PurposePipelineName = "Водовод выс. давл.", Length = 4f, CommissioningYear = 2000, Diameter = 530, Thickness = 9, MaterialName = "13ХФА", InternalCoating = "Нет покрытия", Inhibition = "Да", OuterCoatingOrICCP = "с защитным покрытием без защиты ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = 0.0098f, H2S = "среднее", Soil = "Среднее", StrayCurrents = "да", DefectNum = null, CurrentInternalCorrosionFailures = 8, CurrentOuterCorrosionFailures = 0, LastInternalCorrosionFailures = 1, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 1, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 8, AllOuterCorrosionFailures = 0, Pin = 25f, Pout = 8f, Qliq = 744f, Qgas = null, Qoil = 474f, WaterCut = 26.2f };
data[12] = new PrioritizationFileData() { PurposePipelineName = "Нефтепровод внешнего транспорта", Length = 10.864f, CommissioningYear = 2002, Diameter = 720, Thickness = 10, MaterialName = "Ст.20", InternalCoating = "Нет покрытия", Inhibition = "Да", OuterCoatingOrICCP = "Без покрытия и ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = 0.0098f, H2S = "среднее", Soil = "Среднее", StrayCurrents = "да", DefectNum = null, CurrentInternalCorrosionFailures = 7, CurrentOuterCorrosionFailures = 0, LastInternalCorrosionFailures = 1, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 1, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 7, AllOuterCorrosionFailures = 0, Pin = 25f, Pout = 8f, Qliq = 744f, Qgas = null, Qoil = 474f, WaterCut = 26.2f };
data[13] = new PrioritizationFileData() { PurposePipelineName = "Напорные нефтепроводы", Length = 1.244f, CommissioningYear = 2004, Diameter = 820, Thickness = 12, MaterialName = "Ст.21", InternalCoating = "Нет покрытия", Inhibition = "Да", OuterCoatingOrICCP = "с защитным покрытием без защиты ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = 0.0098f, H2S = "среднее", Soil = "Среднее", StrayCurrents = "нет", DefectNum = null, CurrentInternalCorrosionFailures = 6, CurrentOuterCorrosionFailures = 1, LastInternalCorrosionFailures = 1, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 1, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 6, AllOuterCorrosionFailures = 0, Pin = 25f, Pout = 8f, Qliq = null, Qgas = 700f, Qoil = null, WaterCut = 26.2f };
data[14] = new PrioritizationFileData() { PurposePipelineName = "Нефтепровод внешнего транспорта", Length = 10.864f, CommissioningYear = 2006, Diameter = 300, Thickness = 5, MaterialName = "Ст.20", InternalCoating = "Нет покрытия", Inhibition = "Да", OuterCoatingOrICCP = "Без покрытия и ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = 0.6f, H2S = "среднее", Soil = "Среднее", StrayCurrents = "да", DefectNum = null, CurrentInternalCorrosionFailures = 5, CurrentOuterCorrosionFailures = 0, LastInternalCorrosionFailures = 1, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 1, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 5, AllOuterCorrosionFailures = 0, Pin = 25f, Pout = 8f, Qliq = 744f, Qgas = null, Qoil = 474f, WaterCut = 26.2f };
data[15] = new PrioritizationFileData() { PurposePipelineName = "Напорные нефтепроводы", Length = 4f, CommissioningYear = 2008, Diameter = 325, Thickness = 6, MaterialName = "Ст.21", InternalCoating = "Нет покрытия", Inhibition = "Да", OuterCoatingOrICCP = "с защитным покрытием без защиты ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = 0.0098f, H2S = "среднее", Soil = "Низкое", StrayCurrents = "да", DefectNum = null, CurrentInternalCorrosionFailures = 4, CurrentOuterCorrosionFailures = 0, LastInternalCorrosionFailures = 1, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 1, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 4, AllOuterCorrosionFailures = 0, Pin = 25f, Pout = 8f, Qliq = 744f, Qgas = null, Qoil = 474f, WaterCut = 26.2f };
data[16] = new PrioritizationFileData() { PurposePipelineName = "Нефтепровод внешнего транспорта", Length = 10.864f, CommissioningYear = 2010, Diameter = 350, Thickness = 7, MaterialName = "Ст.20", InternalCoating = "Нет покрытия", Inhibition = "Да", OuterCoatingOrICCP = "Без покрытия и ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = 0.0098f, H2S = "среднее", Soil = "Среднее", StrayCurrents = "да", DefectNum = null, CurrentInternalCorrosionFailures = 3, CurrentOuterCorrosionFailures = 0, LastInternalCorrosionFailures = 1, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 1, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 3, AllOuterCorrosionFailures = 0, Pin = 25f, Pout = 8f, Qliq = 744f, Qgas = null, Qoil = 474f, WaterCut = 26.2f };
data[17] = new PrioritizationFileData() { PurposePipelineName = "Напорные нефтепроводы", Length = 1.244f, CommissioningYear = 2012, Diameter = 426, Thickness = 8, MaterialName = "Ст.21", InternalCoating = "Нет покрытия", Inhibition = "Да", OuterCoatingOrICCP = "с защитным покрытием без защиты ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = 0.4f, H2S = "среднее", Soil = "Среднее", StrayCurrents = "Нет", DefectNum = null, CurrentInternalCorrosionFailures = 2, CurrentOuterCorrosionFailures = 0, LastInternalCorrosionFailures = 0, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 1, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 2, AllOuterCorrosionFailures = 0, Pin = 25f, Pout = 8f, Qliq = 744f, Qgas = null, Qoil = 474f, WaterCut = 26.2f };
data[18] = new PrioritizationFileData() { PurposePipelineName = "Вык. лин. одиночных скв.", Length = 10.864f, CommissioningYear = 2014, Diameter = 500, Thickness = 9, MaterialName = "Ст.20", InternalCoating = "Нет покрытия", Inhibition = "Да", OuterCoatingOrICCP = "Без покрытия и ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = 0.0098f, H2S = "среднее", Soil = "Среднее", StrayCurrents = "да", DefectNum = null, CurrentInternalCorrosionFailures = 1, CurrentOuterCorrosionFailures = 0, LastInternalCorrosionFailures = 0, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 0, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 1, AllOuterCorrosionFailures = 0, Pin = 25f, Pout = 8f, Qliq = 744f, Qgas = null, Qoil = 474f, WaterCut = 70f };
data[19] = new PrioritizationFileData() { PurposePipelineName = "Напорные нефтепроводы", Length = 4f, CommissioningYear = 2016, Diameter = 530, Thickness = 10, MaterialName = "Ст.21", InternalCoating = "Нет покрытия", Inhibition = "Да", OuterCoatingOrICCP = "с защитным покрытием без защиты ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = 0.0098f, H2S = "среднее", Soil = "Низкое", StrayCurrents = "да", DefectNum = null, CurrentInternalCorrosionFailures = 0, CurrentOuterCorrosionFailures = 0, LastInternalCorrosionFailures = 0, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 0, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 0, AllOuterCorrosionFailures = 0, Pin = 25f, Pout = 8f, Qliq = 744f, Qgas = null, Qoil = 474f, WaterCut = 26.2f };
data[20] = new PrioritizationFileData() { PurposePipelineName = "Нефтепровод внешнего транспорта", Length = 10.864f, CommissioningYear = 2018, Diameter = 720, Thickness = 12, MaterialName = "Ст.20", InternalCoating = "Нет покрытия", Inhibition = "Да", OuterCoatingOrICCP = "Без покрытия и ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = 0.1f, H2S = "среднее", Soil = "Среднее", StrayCurrents = "Нет данных", DefectNum = null, CurrentInternalCorrosionFailures = 0, CurrentOuterCorrosionFailures = 0, LastInternalCorrosionFailures = 0, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 0, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 0, AllOuterCorrosionFailures = 0, Pin = 25f, Pout = 8f, Qliq = 744f, Qgas = null, Qoil = 474f, WaterCut = 26.2f };
data[21] = new PrioritizationFileData() { PurposePipelineName = "Напорные нефтепроводы", Length = 5f, CommissioningYear = 2020, Diameter = 820, Thickness = 5, MaterialName = "Ст.21", InternalCoating = "Нет покрытия", Inhibition = "Да", OuterCoatingOrICCP = "с защитным покрытием без защиты ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = 0.0098f, H2S = "среднее", Soil = "Среднее", StrayCurrents = "да", DefectNum = null, CurrentInternalCorrosionFailures = 0, CurrentOuterCorrosionFailures = 0, LastInternalCorrosionFailures = 0, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 0, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 0, AllOuterCorrosionFailures = 0, Pin = 25f, Pout = 8f, Qliq = 744f, Qgas = null, Qoil = 474f, WaterCut = 26.2f };
data[22] = new PrioritizationFileData() { PurposePipelineName = "Нефтепровод внешнего транспорта", Length = 10.864f, CommissioningYear = 2022, Diameter = 300, Thickness = 6, MaterialName = "Ст.20", InternalCoating = "Нет покрытия", Inhibition = "Да", OuterCoatingOrICCP = "Без покрытия и ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = 0.0098f, H2S = "среднее", Soil = "Среднее", StrayCurrents = "да", DefectNum = null, CurrentInternalCorrosionFailures = 0, CurrentOuterCorrosionFailures = 0, LastInternalCorrosionFailures = 0, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 0, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 0, AllOuterCorrosionFailures = 0, Pin = 25f, Pout = 8f, Qliq = 744f, Qgas = null, Qoil = 474f, WaterCut = 26.2f };
data[23] = new PrioritizationFileData() { PurposePipelineName = "Напорные нефтепроводы", Length = 2f, CommissioningYear = 2010, Diameter = 325, Thickness = 7, MaterialName = "Ст.21", InternalCoating = "Нет покрытия", Inhibition = "Да", OuterCoatingOrICCP = "с защитным покрытием без защиты ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = 0.0098f, H2S = "среднее", Soil = "Нет данных", StrayCurrents = "да", DefectNum = null, CurrentInternalCorrosionFailures = 0, CurrentOuterCorrosionFailures = 0, LastInternalCorrosionFailures = 0, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 0, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 0, AllOuterCorrosionFailures = 0, Pin = 25f, Pout = 8f, Qliq = 744f, Qgas = null, Qoil = 474f, WaterCut = 26.2f };
data[24] = new PrioritizationFileData() { PurposePipelineName = "Нефтепровод внешнего транспорта", Length = 10.864f, CommissioningYear = 1978, Diameter = 350, Thickness = 8, MaterialName = "Ст.20", InternalCoating = "Нет покрытия", Inhibition = "Да", OuterCoatingOrICCP = "Без покрытия и ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = 0.0098f, H2S = "среднее", Soil = "Нет данных", StrayCurrents = "да", DefectNum = null, CurrentInternalCorrosionFailures = 0, CurrentOuterCorrosionFailures = 0, LastInternalCorrosionFailures = 0, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 0, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 0, AllOuterCorrosionFailures = 0, Pin = 25f, Pout = 8f, Qliq = 744f, Qgas = null, Qoil = 474f, WaterCut = 26.2f };
data[25] = new PrioritizationFileData() { PurposePipelineName = "Напорные нефтепроводы", Length = 3f, CommissioningYear = 2010, Diameter = 426, Thickness = 9, MaterialName = "Ст.21", InternalCoating = "Нет покрытия", Inhibition = "Да", OuterCoatingOrICCP = "с защитным покрытием без защиты ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = 0.0098f, H2S = "среднее", Soil = "Среднее", StrayCurrents = "да", DefectNum = null, CurrentInternalCorrosionFailures = 0, CurrentOuterCorrosionFailures = 1, LastInternalCorrosionFailures = 0, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 0, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 0, AllOuterCorrosionFailures = 0, Pin = 25f, Pout = 8f, Qliq = 744f, Qgas = null, Qoil = 474f, WaterCut = 26.2f };
data[26] = new PrioritizationFileData() { PurposePipelineName = "Нефтепровод внешнего транспорта", Length = 10.864f, CommissioningYear = 1978, Diameter = 500, Thickness = 10, MaterialName = "Ст.20", InternalCoating = "Нет покрытия", Inhibition = "Да", OuterCoatingOrICCP = "Без покрытия и ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = 0.0098f, H2S = "среднее", Soil = "Среднее", StrayCurrents = "да", DefectNum = null, CurrentInternalCorrosionFailures = 0, CurrentOuterCorrosionFailures = 0, LastInternalCorrosionFailures = 0, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 0, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 0, AllOuterCorrosionFailures = 0, Pin = 25f, Pout = 8f, Qliq = 744f, Qgas = null, Qoil = 474f, WaterCut = 70f };
data[27] = new PrioritizationFileData() { PurposePipelineName = "Напорные нефтепроводы", Length = 1f, CommissioningYear = 2010, Diameter = 530, Thickness = 12, MaterialName = "Ст.21", InternalCoating = "Нет покрытия", Inhibition = "Да", OuterCoatingOrICCP = "с защитным покрытием без защиты ЭХЗ", SER = 2016, AcousticEmission = null, ILI = 2016, HI = null, SI = null, UD = null, Pigging = "Проводится", AvgCorrosionRate = 0.0098f, H2S = "среднее", Soil = "Среднее", StrayCurrents = "да", DefectNum = 5, CurrentInternalCorrosionFailures = 0, CurrentOuterCorrosionFailures = 0, LastInternalCorrosionFailures = 0, LastOuterCorrosionFailures = 0, YearInternalCorrosionFailures = 0, YearOuterCorrosionFailures = 0, AllInternalCorrosionFailures = 0, AllOuterCorrosionFailures = 0, Pin = 25f, Pout = 8f, Qliq = 744f, Qgas = null, Qoil = 474f, WaterCut = 26.2f };
var model = new PrioritizationModel(2023);
var factors = model.Fit(data);
var data2 = new PrioritizationFileDataExt[3];
data2[0] = new PrioritizationFileDataExt()
PurposePipelineName = "Нефтесборные сети",
CommissioningYear = 1978,
InternalCoating = "Нет покрытия",
OuterCoatingOrICCP = "Без покрытия и ЭХЗ",
Pigging = "Не проводится",
AvgCorrosionRate = 0.0098f,
CurrentInternalCorrosionFailures = 0,
CurrentOuterCorrosionFailures = 0,
LastInternalCorrosionFailures = 0,
LastOuterCorrosionFailures = 0,
YearInternalCorrosionFailures = 0,
YearOuterCorrosionFailures = 0,
AllInternalCorrosionFailures = 0,
AllOuterCorrosionFailures = 0,
RegulatoryCompliance = false,
RejectionThickness = 5.8f,
NextYearDefectNumbers = 3,
UnresolvedInvalidDefectNumbers = 1,
RepairedNextYearDefectNumbers = 1,
RepairedUnresolvedInvalidDefectNumbers = 1,
RepairedDefectNumbers = 2,
OperatorName = "Оренбургнефть",
LandCategory = "Сельскохозяйственные",
FailoverPlanTime = "≤ 18",
LayingPipeline = "Пересечение оврагов, ручьев",
WaterBodyLocation = "Другие водные объекты",
PipelineType = "Линейный трубопровод"
data2[1] = new PrioritizationFileDataExt()
PurposePipelineName = "Нефтесборные сети",
CommissioningYear = 2000,
InternalCoating = "Нет покрытия",
OuterCoatingOrICCP = "с защитным покрытием без защиты ЭХЗ",
AvgCorrosionRate = 0.0098f,
CurrentInternalCorrosionFailures = 0,
CurrentOuterCorrosionFailures = 0,
LastInternalCorrosionFailures = 0,
LastOuterCorrosionFailures = 0,
YearInternalCorrosionFailures = 0,
YearOuterCorrosionFailures = 0,
AllInternalCorrosionFailures = 0,
AllOuterCorrosionFailures = 0,
RegulatoryCompliance = true,
RejectionThickness = 5.8f,
NextYearDefectNumbers = 3,
UnresolvedInvalidDefectNumbers = 1,
RepairedNextYearDefectNumbers = 1,
RepairedUnresolvedInvalidDefectNumbers = 1,
RepairedDefectNumbers = 2,
OperatorName = "Оренбургнефть",
LandCategory = "Сельскохозяйственные",
FailoverPlanTime = "≤ 18",
LayingPipeline = "Пересечение оврагов, ручьев",
WaterBodyLocation = "Другие водные объекты",
PipelineType = "Линейный трубопровод"
data2[2] = new PrioritizationFileDataExt()
PurposePipelineName = "Нефтесборные сети",
CommissioningYear = 2005,
MaterialName = "Ст.09Г2С",
InternalCoating = "Нет покрытия",
OuterCoatingOrICCP = "Без покрытия и ЭХЗ",
Pigging = "Не проводится",
AvgCorrosionRate = 0.0098f,
CurrentInternalCorrosionFailures = 0,
CurrentOuterCorrosionFailures = 0,
LastInternalCorrosionFailures = 0,
LastOuterCorrosionFailures = 0,
YearInternalCorrosionFailures = 0,
YearOuterCorrosionFailures = 0,
AllInternalCorrosionFailures = 0,
AllOuterCorrosionFailures = 0,
RegulatoryCompliance = true,
RejectionThickness = 5.8f,
NextYearDefectNumbers = 3,
UnresolvedInvalidDefectNumbers = 1,
RepairedNextYearDefectNumbers = 1,
RepairedUnresolvedInvalidDefectNumbers = 1,
RepairedDefectNumbers = 2,
OperatorName = "Оренбургнефть",
LandCategory = "Сельскохозяйственные",
FailoverPlanTime = "≤ 18",
LayingPipeline = "Пересечение оврагов, ручьев",
WaterBodyLocation = "Другие водные объекты",
PipelineType = "Линейный трубопровод"
var res = model.RiskPredict(factors, data2);
foreach (var v in res) Console.WriteLine("{0}", v.Item1.NormalizedTotalProbability);
public (PrioritizationResult, DamageResult)[] RiskPredict(PrioritizationModelFactors factors, PrioritizationFileData[] data)
return this.RiskPredict(factors, this.Convert(data));
public (PrioritizationResult, DamageResult)[] RiskPredict(PrioritizationModelFactors factors, PrioritizationData[] data)
var assessment = new Assessment();
var damage = data.Select(o => assessment.Assess(o)).ToArray();
var maxDamage = damage.Max(o => o.TotalDamage);
var damageUnit = damage.Select(o => o.TotalDamage / maxDamage);
var results = data.Zip(damageUnit, (x, y) => Predicting.Predict(factors, x, y)).ToArray();
return results.Zip(damage, (x, y) => (x,y)).ToArray();
private static void Normilize(PrioritizationResult[] results)
var max = results.Where(o => o.TotalProbability < 100).Max(o => o.TotalProbability);
var min = results.Where(o => o.TotalProbability < 100).Min(o => o.TotalProbability);
var scale = 100 / (max - min);
var tmp = results.Select(o => o.TotalProbability < 100 ? (o.TotalProbability - min) * scale : 100).ToArray();
for (int i = 0; i < results.Count(); i++)
results[i].NormalizedTotalProbability =
results[i].CriticalAgeProbability > 0f && results[i].CriticalAgeProbability > tmp[i] / 100f ?
100 * results[i].CriticalAgeProbability :
public class PrioritizationResult
public float RegulatoryComplianceProbability { get; set; }
public float RejectionThicknessProbability { get; set; }
public float UnresolvedInvalidDefectsProbability { get; set; }
public float PredictAge { get; set; }
public float PredictMaterial { get; set; }
public float PredictLastYearFailure { get; set; }
public float PredictAllFailure { get; set; }
public float PredictPurposePipeline { get; set; }
public float PredictWaterCut { get; set; }
public float PredictInternalCoating { get; set; }
public float PredictInhibition { get; set; }
public float PredictCorrosionRate { get; set; }
public float PredictH2S { get; set; }
public float PredictCurrents { get; set; }
public float PredictSoilCorrosivity { get; set; }
public float PredictOuterCoating { get; set; }
public float PredictPigging { get; set; }
public float PredictInspection { get; set; }
public float PredictFluidVelocity { get; set; }
public float Average { get; set; }
public float TotalProbability { get; set; }
public float CriticalAgeProbability { get; set; }
public float NormalizedTotalProbability { get; set; }
public static FluidType ToFluid(string purpose)
return (new Dictionary<string, FluidType>(StringComparer.OrdinalIgnoreCase)
{"Водовод низк. давл. товарной воды", FluidType.reservoir_water },
{"Водовод низк. давл. пресной воды", FluidType.fresh_water },
{"Водовод выс. давл.", FluidType.fresh_water },
{"Газопроводы выс. давл.", FluidType.gas },
{"Газопроводы низк. давл.", FluidType.gas },
{"Напорные нефтепроводы", FluidType.production_oil },
{"Нефтесборные сети", FluidType.production_oil },
{"Нефтепровод внешнего транспорта", FluidType.crude_oil },
{"Вык. лин. одиночных скв.", FluidType.production_oil }
}).ToCode(purpose, FluidType.production_oil);
public static PrioritizationResult Predict(PrioritizationModelFactors factors, PrioritizationData data, float DamageUnit)
var result = new PrioritizationResult();
result.RegulatoryComplianceProbability = data.RegulatoryCompliance ? 0f : 1f;
result.RejectionThicknessProbability = Predicting.PredictRejectionThickness(factors, data);
result.UnresolvedInvalidDefectsProbability = data.UnresolvedInvalidDefects ? 1f : 0f;
var MaxBaseProbability = Math.Max(
result.RegulatoryComplianceProbability,
result.RejectionThicknessProbability),
result.UnresolvedInvalidDefectsProbability);
var probability = new float[17];
probability[0] = Predicting.PredictAge(factors, data.CurrentAge);
result.PredictAge = probability[0];
probability[1] = Predicting.PredictMaterial(factors, data);
result.PredictAge = probability[1];
probability[2] = Predicting.PredictLastYearFailure(factors, data);
result.PredictAge = probability[2];
probability[3] = Predicting.PredictAllFailure(factors, data);
result.PredictAge = probability[3];
probability[4] = Predicting.PredictPurposePipeline(factors, data);
result.PredictPurposePipeline = probability[4];
probability[5] = Predicting.PredictWaterCut(factors, data);
result.PredictWaterCut = probability[5];
probability[6] = Predicting.PredictInternalCoating(factors, data);
result.PredictInternalCoating = probability[6];
probability[7] = Predicting.PredictInhibition(factors, data);
result.PredictInhibition = probability[7];
probability[8] = Predicting.PredictCorrosionRate(factors, data);
result.PredictCorrosionRate = probability[8];
probability[9] = Predicting.PredictH2S(factors, data);
result.PredictH2S = probability[9];
probability[10] = Predicting.PredictCurrents(factors, data);
result.PredictCurrents = probability[10];
probability[11] = Predicting.PredictSoilCorrosivity(factors, data);
result.PredictSoilCorrosivity = probability[11];
probability[12] = Predicting.PredictOuterCoating(factors, data);
result.PredictOuterCoating = probability[12];
probability[13] = Predicting.PredictPigging(factors, data);
result.PredictPigging = probability[13];
probability[14] = Predicting.PredictInspection(factors, data);
result.PredictInspection = probability[14];
probability[15] = Predicting.PredictFluidVelocity(factors, data);
result.PredictFluidVelocity = probability[15];
var AvgProbability = probability.Average();
result.TotalProbability = Math.Max(MaxBaseProbability, AvgProbability);
result.TotalProbability = 100 * Math.Min(1f, Math.Max(0.01f, result.TotalProbability));
result.CriticalAgeProbability = Predicting.PredictCriticalAge(factors, data, DamageUnit);
public static ValueTuple<int?, int?, int, float> GetMaterialPrams(string name)
return (new Dictionary<string, ValueTuple<int?, int?, int, float>>(StringComparer.OrdinalIgnoreCase)
{"12СГБ", (420, 400, 1, 0.8f)},
{"13ХФА", (420, 400, 1, 0.8f)},
{"14ГС", (420, 400, 1, 0.8f)},
{"17ГС", (420, 400, 1, 0.8f)},
{"17ПСУ", (420, 400, 1, 0.8f)},
{"Ст 10", (420, 400, 1, 0.8f)},
{"Ст 20", (420, 400, 1, 0.8f)},
{"Ст10Г2С", (420, 400, 1, 0.8f)},
{"футур", (420, 400, 1, 0.8f)},
{"чугун", (420, 400, 1, 0.8f)},
{"09ВМ3", (420, 400, 1, 0.8f)},
{"09ГСФ", (420, 400, 1, 0.8f)},
{"10Г2ФБЮ", (420, 400, 1, 0.8f)},
{"10ПС", (420, 400, 1, 0.8f)},
{"14ХГС", (420, 400, 1, 0.8f)},
{"17Г1С", (420, 400, 1, 0.8f)},
{"17Г1С-У", (420, 400, 1, 0.8f)},
{"17Г2СФ", (420, 400, 1, 0.8f)},
{"20А", (420, 400, 1, 0.8f)},
{"20В", (420, 400, 1, 0.8f)},
{"20КСХ", (420, 400, 1, 0.8f)},
{"20ПС", (420, 400, 1, 0.8f)},
{"20С", (420, 400, 1, 0.8f)},
{"20СП", (420, 400, 1, 0.8f)},
{"20ФА", (420, 400, 1, 0.8f)},
{"20ХФ", (420, 400, 1, 0.8f)},
{"3СП НКТ", (420, 400, 1, 0.8f)},
{"ГПМТ", (null, null, 0, 0.8f)},
{"МПТ", (null, null, 0, 0.8f)},
{"Нет данных", (420, 400, 1, 0.8f)},
{"Неметаллическое покрытие", (null, null, 0, 0.8f)},
{"Ст09Г2С", (420, 400, 1, 0.8f)},
{"Ст.2", (420, 400, 1, 0.8f)},
{"Ст.3", (420, 400, 1, 0.8f)},
{"Ст.3СП", (420, 400, 1, 0.8f)},
{"Ст.08ХМФЧА", (420, 400, 1, 0.8f)},
{"Ст.09Г2С", (420, 400, 1, 0.8f)},
{"Ст.09ГСФ", (420, 400, 1, 0.8f)},
{"Ст.10", (420, 400, 1, 0.8f)},
{"Ст.10Г2", (420, 400, 1, 0.8f)},
{"Ст.10Г2А", (420, 400, 1, 0.8f)},
{"Ст.10ГС", (420, 400, 1, 0.8f)},
{"Ст.10Г2ФБЮ", (420, 400, 1, 0.8f)},
{"Ст.10КП", (420, 400, 1, 0.8f)},
{"Ст.10ПС", (420, 400, 1, 0.8f)},
{"Ст.10СН", (420, 400, 1, 0.8f)},
{"Ст.10СП", (420, 400, 1, 0.8f)},
{"Ст.10СП3", (420, 400, 1, 0.8f)},
{"Ст.13ГФА", (420, 400, 1, 0.8f)},
{"Ст.13ХФА", (420, 400, 1, 0.8f)},
{"Ст.15ГСТЮ", (420, 400, 1, 0.8f)},
{"Ст.15ХФА", (420, 400, 1, 0.8f)},
{"Ст.15ХМФА", (420, 400, 1, 0.8f)},
{"Ст.17ГС", (420, 400, 1, 0.8f)},
{"Ст.17Г1С", (420, 400, 1, 0.8f)},
{"Ст.17Г2СФ", (420, 400, 1, 0.8f)},
{"Ст.19", (420, 400, 1, 0.8f)},
{"Ст.20", (420, 400, 1, 0.8f)},
{"Ст.20А", (420, 400, 1, 0.8f)},
{"Ст.20В", (420, 400, 1, 0.8f)},
{"Ст.20С", (420, 400, 1, 0.8f)},
{"Ст.20Л", (420, 400, 1, 0.8f)},
{"Ст.20Ф", (420, 400, 1, 0.8f)},
{"Ст.20ГС", (420, 400, 1, 0.8f)},
{"Ст.20СА", (420, 400, 1, 0.8f)},
{"Ст.20СП", (420, 400, 1, 0.8f)},
{"Ст.20СФ", (420, 400, 1, 0.8f)},
{"Ст.20ПС", (420, 400, 1, 0.8f)},
{"Ст.20ХФ", (420, 400, 1, 0.8f)},
{"Ст.20ХФА", (420, 400, 1, 0.8f)},
{"Ст.20ФА", (420, 400, 1, 0.8f)},
{"Ст.20ЮЧ", (420, 400, 1, 0.8f)},
{"Ст.21", (420, 400, 1, 0.8f)},
{"Ст.22", (420, 400, 1, 0.8f)},
{"Ст.22A", (420, 400, 1, 0.8f)},
{"Ст.22ГЮ", (420, 400, 1, 0.8f)},
{"Ст.35", (420, 400, 1, 0.8f)},
{"Ст.45", (420, 400, 1, 0.8f)},
{"Амерон", (null, null, 0, 0.8f)},
{"Армпласт", (null, null, 0, 0.8f)},
{"КГТ", (null, null, 0, 0.8f)},
{"КСР", (null, null, 0, 0.8f)},
{"НКТ", (null, null, 0, 0.8f)},
{"ПАМ", (null, null, 0, 0.8f)},
{"ПАН", (null, null, 0, 0.8f)},
{"ПАТ", (null, null, 0, 0.8f)},
{"ППТ", (null, null, 0, 0.8f)},
{"Сарпласт", (null, null, 0, 0.8f)},
{"Стеклопластик", (null, null, 0, 0.8f)},
{"ТАН", (null, null, 0, 0.8f)},
{"ТСК", (null, null, 0, 0.8f)},
{"ТСТ", (null, null, 0, 0.8f)},
{"Футер", (420, 400, 1, 0.8f)},
{"/X-70/ Италия", (420, 400, 1, 0.8f)},
{"Другое", (420, 400, 1, 0.8f)},
{"Не определен", (420, 400, 1, 0.8f)},
{"12ГСБ", (420, 400, 1, 0.8f)},
{"09Г2С", (420, 400, 1, 0.8f)},
{"06ХФ", (420, 400, 1, 0.8f)},
{"10СП", (420, 400, 1, 0.8f)},
{"3СП", (420, 400, 1, 0.8f)},
{"вст3сп", (420, 400, 1, 0.8f)}
}).ToCode(name, (420, 400, 1, 0.8f));
public static float GetPredictRejectionThicknessFactor(FluidType fluid)
return (new Dictionary<FluidType, float>()
{FluidType.crude_oil, 0.75f},
{FluidType.production_oil, 0.75f},
{FluidType.reservoir_water, 0.9f},
{FluidType.fresh_water, 0.9f}
public static float GetNominalRejectionThickness(float d)
else if (d >= 125 && d < 250)
else if (d >= 250 && d < 350)
else if (d >= 350 && d < 400)
public static float GetRejectionThickness(PrioritizationModelFactors factors, PrioritizationData data)
var p = Predicting.GetMaterialPrams(data.Material);
var fluidFactor = GetPredictRejectionThicknessFactor(ToFluid(data.PurposePipeline));
var condition = fluidFactor * p.Item2 / p.Item1;
float numerator = 1.2f * (data.InletPressure / 10f) * 1f * (data.Diameter / 1000f);
float f1 = numerator / (2f * (p.Item1 ?? 0 * 0.8f * fluidFactor * p.Item4 + 1.2f * (data.InletPressure / 10f)));
float f2 = numerator / (2f * (0.9f * p.Item2 ?? 0 + 1.2f * (data.InletPressure / 10)));
catch (Exception) { return 0f; }
public static float PredictRejectionThickness(PrioritizationModelFactors factors, PrioritizationData data)
if (data.RejectionThickness.HasValue)
return data.RejectionThickness.Value > Math.Max(GetNominalRejectionThickness(data.Diameter),
GetRejectionThickness(factors, data)) ? 0f : 1f;
public static float PredictCriticalAge(PrioritizationModelFactors factors, PrioritizationData data, float DamageUnit)
if (data.CurrentAge < factors.CriticalAge[data.PurposePipeline])
else if (data.AllInternalCorrosionFailures > 0)
else if (DamageUnit > 0.8f)
else if (DamageUnit > 0.7f)
else if (DamageUnit > 0.6f)
else if (DamageUnit > 0.5f)
else if (DamageUnit > 0.4f)
else if (DamageUnit > 0.25f)
catch (Exception) { return 0f; }
public static float PredictAge(PrioritizationModelFactors factors, int age)
return factors.FailureProbability[PrioritizationModelFactors.FailureProbabilityCodes.FromAge(age)];
internal static float PredictMaterial(PrioritizationModelFactors factors, PrioritizationData data)
return factors.PipeMaterial[PrioritizationModelFactors.PipeMaterialCodes.FromMaterialCode(data.MaterialCode)];
internal static float PredictLastYearFailure(PrioritizationModelFactors factors, PrioritizationData data)
return factors.LastYearFailure[PrioritizationModelFactors.FailureCodes.FromFailure(data.LastInternalCorrosionFailures)];
internal static float PredictAllFailure(PrioritizationModelFactors factors, PrioritizationData data)
return factors.AllFailure[PrioritizationModelFactors.FailureCodes.FromFailure(data.AllInternalCorrosionFailures)];
internal static float PredictPurposePipeline(PrioritizationModelFactors factors, PrioritizationData data)
return factors.PurposePipeline[data.PurposePipeline];
internal static float PredictWaterCut(PrioritizationModelFactors factors, PrioritizationData data)
return factors.WaterCut[PrioritizationModelFactors.WaterCutCodes.FromWaterCutCode(data.WaterCut)];
internal static float PredictInternalCoating(PrioritizationModelFactors factors, PrioritizationData data)
return factors.InternalCoating[PrioritizationModelFactors.InternalCoatingCodes.FromInternalCoatingCode(data.InternalCoating)];
internal static float PredictInhibition(PrioritizationModelFactors factors, PrioritizationData data)
return factors.Inhibition[PrioritizationModelFactors.InhibitionCodes.FromInhibition(data.IsInhibition)];
internal static float PredictCorrosionRate(PrioritizationModelFactors factors, PrioritizationData data)
return factors.CorrosionRate[PrioritizationModelFactors.CorrosionRateCodes.FromCorrosionRateCode(data.AvgCorrosionRate)];
internal static float PredictH2S(PrioritizationModelFactors factors, PrioritizationData data)
return factors.H2S[PrioritizationModelFactors.H2SCodes.FromH2SCode(data.H2S)];
internal static float PredictCurrents(PrioritizationModelFactors factors, PrioritizationData data)
return factors.Currents[PrioritizationModelFactors.CurrentsCodes.FromCurrentsCode(data.StrayCurrents)];
internal static float PredictSoilCorrosivity(PrioritizationModelFactors factors, PrioritizationData data)
return factors.SoilCorrosivity[PrioritizationModelFactors.SoilCorrosivityCodes.FromSoilCorrosivityCode(data.Soil)];
internal static float PredictOuterCoating(PrioritizationModelFactors factors, PrioritizationData data)
return factors.OuterCoating[PrioritizationModelFactors.OuterCoatingCodes.FromOuterCoatingCode(data.OuterCoatingOrICCP)];
internal static float PredictFluidVelocity(PrioritizationModelFactors factors, PrioritizationData data)
return factors.FluidVelocity[PrioritizationModelFactors.FluidVelocityCodes.FromFluidVelocityCode(data.FluidVelocity)];
internal static float PredictPigging(PrioritizationModelFactors factors, PrioritizationData data)
return factors.Pigging[PrioritizationModelFactors.PiggingCodes.FromPigging(data.IsPigging)];
internal static float PredictInspection(PrioritizationModelFactors factors, PrioritizationData data)
return factors.Inspection[PrioritizationModelFactors.InspectionCodes.FromDiagnocticCode(data.Diagnoctic)];
public class DamageResult
public float FailureNumber { get; set; }
public float TotalEquipmentRecovery
return WithoutFillingLinePipelines + WithoutFillingWaterCrossings
+ WithoutFillingRailwayCrossing + WithoutFillingFederalRoadsCrossing
+ WithFillingLinePipelines + WithFillingWaterCrossings
+ WithFillingRailwayCrossing + WithFillingFederalRoadsCrossing;
public float MassOilLoss { get; set; }
public float OilLoss { get; set; }
public float MassWaterLoss { get; set; }
public float WaterLoss { get; set; }
public float VolumeGasLoss { get; set; }
public float GasLoss { get; set; }
public float MassOilShortage { get; set; }
public float OilShortage { get; set; }
public float LandReclamationArea { get; set; }
public float LandReclamationCosts { get; set; }
public float WaterBodiesRestorationCosts { get; set; }
public float TotalPenalties { get; set; }
public float TotalDamage { get; set; }
public float WithoutFillingLinePipelines { get; internal set; }
public float WithoutFillingWaterCrossings { get; internal set; }
public float WithoutFillingRailwayCrossing { get; internal set; }
public float WithoutFillingFederalRoadsCrossing { get; internal set; }
public float WithFillingLinePipelines { get; internal set; }
public float WithFillingWaterCrossings { get; internal set; }
public float WithFillingRailwayCrossing { get; internal set; }
public float WithFillingFederalRoadsCrossing { get; internal set; }
public float LandLaw_8_1 { get; internal set; }
public float CXB { get; internal set; }
public float Kg { get; internal set; }
public float Kin { get; internal set; }
public float Kdp { get; internal set; }
public float Tx { get; internal set; }
public float Kish { get; internal set; }
public float PotentialPenalty { get; internal set; }
public float FactPenalty { get; internal set; }
public float DamageForestedAreas { get; internal set; }
public float TotalLandPenalty { get; internal set; }
public float WaterBodyLaw_8_1 { get; internal set; }
public float Kvg { get; internal set; }
public float Kv { get; internal set; }
public float Tax { get; internal set; }
public float DamageWaterBody { get; internal set; }
public float WaterBodyPenalty { get; internal set; }
public float GasPenalty { get; internal set; }
public DamageResult Assess(PrioritizationData data)
var result = new DamageResult();
result.FailureNumber = Assessment.AssessmentFailureNumber(data);
AssessmentTotalEquipmentRecovery(data, result);
AssessmentOilLoss(data, result);
AssessmentWaterLoss(data, result);
AssessmentGasLoss(data, result);
AssessmentOilShortage(data, result);
AssessmentLandReclamationCosts(data, result);
AssessmentWaterBodiesRestorationCosts(data, result);
AssessmentTotalPenalties(data, result);
public ValueTuple<float, float, float, float, float, float, float> GetCosts1(OperatorNameCode name)
return (new Dictionary<OperatorNameCode, ValueTuple<float, float, float, float, float, float, float>>()
{ OperatorNameCode.Vankorneft, (0.009f, 0f, 0.002f, 0.9f, 0.0125f, 1.2f, 1.27f) },
{ OperatorNameCode.Varyoganneftegaz, (0.009f, 0f, 0.002f, 0.9f, 0.0125f, 1.2f, 1.22f) },
{ OperatorNameCode.Vostsibneftegaz, (0.009f, 0f, 0.002f, 0.9f, 0.0125f, 1.2f, 1.23f) },
{ OperatorNameCode.VCNG, (0.009f, 0f, 0.002f, 0.9f, 0.0125f, 1.2f, 1.22f) },
{ OperatorNameCode.Grozneftegaz, (0.009f, 0f, 0.002f, 0.9f, 0.0125f, 1.2f, 1.55f) },
{ OperatorNameCode.Dagneft, (0.009f, 0f, 0.002f, 0.9f, 0.0125f, 1.2f, 1.39f) },
{ OperatorNameCode.Dagneftegaz, (0.009f, 0f, 0.002f, 0.9f, 0.0125f, 1.2f, 1.39f) },
{ OperatorNameCode.Ingneft, (0.009f, 0f, 0.002f, 0.9f, 0.0125f, 1.2f, 1.39f) },
{ OperatorNameCode.Krasnodarneftegaz, (0.009f, 0f, 0.002f, 0.9f, 0.0125f, 1.2f, 1.95f) },
{ OperatorNameCode.Nyagan, (0.011f, 0f, 0.001f, 2.076181f, 0.0125f, 2.1f, 1.22f) },
{ OperatorNameCode.Orenburgneft, (0.009f, 0f, 0.002f, 0.9f, 0.0125f, 1.2f, 1.6f) },
{ OperatorNameCode.PolarLights, (0.009f, 0f, 0.002f, 0.9f, 0.0125f, 1.2f, 1.3f) },
{ OperatorNameCode.Purneftegaz, (0.009f, 0f, 0.002f, 0.9f, 0.0125f, 1.2f, 1.22f) },
{ OperatorNameCode.Rospan, (0.009f, 0f, 0.002f, 0.9f, 0.0125f, 1.2f, 1.22f) },
{ OperatorNameCode.Samaraneftegaz, (0.013f, 0f, 0.002f, 0.341f, 0.0125f, 1.2f, 1.4f) },
{ OperatorNameCode.Samotlorneftegaz, (0.009f, 0f, 0.002f, 0.9f, 0.0125f, 1.2f, 1.22f) },
{ OperatorNameCode.Sakhalinmorneftegaz, (0.009f, 0f, 0.002f, 0.9f, 0.0125f, 1.2f, 1.27f) },
{ OperatorNameCode.NorthernOil, (0.009f, 0f, 0.002f, 0.9f, 0.0125f, 1.2f, 1.37f) },
{ OperatorNameCode.Stavropolneftegaz, (0.009f, 0f, 0.002f, 0.9f, 0.0125f, 1.2f, 1.39f) },
{ OperatorNameCode.Tomskneft, (0.009f, 0f, 0.002f, 0.9f, 0.0125f, 1.2f, 1.22f) },
{ OperatorNameCode.Uvat, (0.009f, 0f, 0.002f, 0.9f, 0.0125f, 1.2f, 1.22f) },
{ OperatorNameCode.Udmurtneft, (0.013f, 0f, 0.002f, 0.341f, 0.0125f, 1.2f, 1.41f) },
{ OperatorNameCode.Yuganskneftegaz, (0.009f, 0f, 0.002f, 0.9f, 0.0125f, 1.2f, 1.22f) },
{ OperatorNameCode.BashneftDobycha, (0.009f, 0f, 0.002f, 0.9f, 0.0125f, 1.2f, 1.22f) }
}).ToCode(name, (0.009f, 0f, 0.002f, 0.9f, 0.0125f, 1.2f, 1.22f));
public ValueTuple<float, float, float, float, float, float, float> GetCosts2(OperatorNameCode name)
return (new Dictionary<OperatorNameCode, ValueTuple<float, float, float, float, float, float, float>>()
{ OperatorNameCode.Vankorneft,(0.0009f, 0.0442f, 0.07f, 0.06f, 0.05f, 0.08f, 0.002f)},
{ OperatorNameCode.Varyoganneftegaz,(0.0005f, 0.0442f, 0.07f, 0.06f, 0.05f, 0.08f, 0.002f)},
{ OperatorNameCode.Vostsibneftegaz,(0.0005f, 0.0442f, 0.07f, 0.06f, 0.05f, 0.08f, 0.002f)},
{ OperatorNameCode.VCNG,(0.0005f, 0.0442f, 0.07f, 0.06f, 0.05f, 0.08f, 0.002f)},
{ OperatorNameCode.Grozneftegaz,(0.0007f, 0.034f, 0.07f, 0.06f, 0.05f, 0.08f, 0.002f)},
{ OperatorNameCode.Dagneft,(0.0007f, 0.034f, 0.07f, 0.06f, 0.05f, 0.08f, 0.002f)},
{ OperatorNameCode.Dagneftegaz,(0.0007f, 0.034f, 0.07f, 0.06f, 0.05f, 0.08f, 0.002f)},
{ OperatorNameCode.Ingneft,(0.0007f, 0.034f, 0.07f, 0.06f, 0.05f, 0.08f, 0.002f)},
{ OperatorNameCode.Krasnodarneftegaz,(0.0006f, 0.034f, 0.07f, 0.06f, 0.05f, 0.08f, 0.002f)},
{ OperatorNameCode.Nyagan,(0.0005f, 0.02f, 0.06f, 0.06f, 0.06f, 0.05f, 0.12f)},
{ OperatorNameCode.Orenburgneft,(0.00055f, 0.034f, 0.07f, 0.06f, 0.05f, 0.08f, 0.002f)},
{ OperatorNameCode.PolarLights,(0.0005f, 0.0442f, 0.07f, 0.06f, 0.05f, 0.08f, 0.002f)},
{ OperatorNameCode.Purneftegaz,(0.0005f, 0.0442f, 0.07f, 0.06f, 0.05f, 0.08f, 0.002f)},
{ OperatorNameCode.Rospan,(0.0005f, 0.0442f, 0.07f, 0.06f, 0.05f, 0.08f, 0.002f)},
{ OperatorNameCode.Samaraneftegaz,(0.0006f, 0.0205f, 0.0205f, 0.0205f, 0.0205f, 0.0205f, 0.0205f)},
{ OperatorNameCode.Samotlorneftegaz,(0.0005f, 0.0442f, 0.07f, 0.06f, 0.05f, 0.08f, 0.002f)},
{ OperatorNameCode.Sakhalinmorneftegaz,(0.0005f, 0.0442f, 0.07f, 0.06f, 0.05f, 0.08f, 0.002f)},
{ OperatorNameCode.NorthernOil,(0.0005f, 0.0442f, 0.07f, 0.06f, 0.05f, 0.08f, 0.002f)},
{ OperatorNameCode.Stavropolneftegaz,(0.0006f, 0.034f, 0.07f, 0.06f, 0.05f, 0.08f, 0.002f)},
{ OperatorNameCode.Tomskneft,(0.0005f, 0.0442f, 0.07f, 0.06f, 0.05f, 0.08f, 0.002f)},
{ OperatorNameCode.Uvat,(0.0005f, 0.0442f, 0.07f, 0.06f, 0.05f, 0.08f, 0.002f)},
{ OperatorNameCode.Udmurtneft,(0.0006f, 0.0205f, 0.0205f, 0.0205f, 0.0205f, 0.0205f, 0.0205f)},
{ OperatorNameCode.Yuganskneftegaz,(0.0005f, 0.0442f, 0.07f, 0.06f, 0.05f, 0.08f, 0.002f)},
{ OperatorNameCode.BashneftDobycha,(0.0005f, 0.0442f, 0.07f, 0.06f, 0.05f, 0.08f, 0.002f)}
}).ToCode(name, (0.0005f, 0.0442f, 0.07f, 0.06f, 0.05f, 0.08f, 0.002f));
public ValueTuple<float, float, float, float> GetCosts3(OperatorNameCode name)
return (new Dictionary<OperatorNameCode, ValueTuple<float, float, float, float>>()
{ OperatorNameCode.Vankorneft, (0.003f, 0.004f, 0f, 0.000225f)},
{ OperatorNameCode.Varyoganneftegaz, (0.003f, 0.004f, 0f, 0.000225f)},
{ OperatorNameCode.Vostsibneftegaz, (0.003f, 0.004f, 0f, 0.000225f)},
{ OperatorNameCode.VCNG, (0.003f, 0.004f, 0f, 0.000225f)},
{ OperatorNameCode.Grozneftegaz, (0.003f, 0.004f, 0f, 0.000225f)},
{ OperatorNameCode.Dagneft, (0.003f, 0.004f, 0f, 0.000225f)},
{ OperatorNameCode.Dagneftegaz, (0.003f, 0.004f, 0f, 0.000225f)},
{ OperatorNameCode.Ingneft, (0.003f, 0.004f, 0f, 0.000225f)},
{ OperatorNameCode.Krasnodarneftegaz, (0.003f, 0.004f, 0f, 0.000225f)},
{ OperatorNameCode.Nyagan, (0.05f, 0.05f, 15f, 0.000225f)},
{ OperatorNameCode.Orenburgneft, (0.003f, 0.004f, 0f, 0.000225f)},
{ OperatorNameCode.PolarLights, (0.003f, 0.004f, 0f, 0.000225f)},
{ OperatorNameCode.Purneftegaz, (0.003f, 0.004f, 0f, 0.000225f)},
{ OperatorNameCode.Rospan, (0.003f, 0.004f, 0f, 0.000225f)},
{ OperatorNameCode.Samaraneftegaz, (0.0205f, 0.0205f, 15f, 0.000225f)},
{ OperatorNameCode.Samotlorneftegaz, (0.003f, 0.004f, 0f, 0.000225f)},
{ OperatorNameCode.Sakhalinmorneftegaz, (0.003f, 0.004f, 0f, 0.000225f)},
{ OperatorNameCode.NorthernOil, (0.003f, 0.004f, 0f, 0.000225f)},
{ OperatorNameCode.Stavropolneftegaz, (0.003f, 0.004f, 0f, 0.000225f)},
{ OperatorNameCode.Tomskneft, (0.003f, 0.004f, 0f, 0.000225f)},
{ OperatorNameCode.Uvat, (0.003f, 0.004f, 0f, 0.000225f)},
{ OperatorNameCode.Udmurtneft, (0.0205f, 0.0205f, 15f, 0.000225f)},
{ OperatorNameCode.Yuganskneftegaz, (0.003f, 0.004f, 0f, 0.000225f)},
{ OperatorNameCode.BashneftDobycha, (0.003f, 0.004f, 0f, 0.000225f)}
}).ToCode(name, (0.003f, 0.004f, 0f, 0.000225f));
public ValueTuple<float, float, float> GetPenlties()
return (0.02f, 0.1f, 0.06f);
public ValueTuple<float, float, float> GetForestPenalties()
return (120.96f, 1.51f, 4f);
public float GetIndexingFactor()
public ValueTuple<float, float> GetGasPenalties()
public static float AssessmentFailureNumber(PrioritizationData data)
const float RepairDefectFailureProbability = 0.4f;
return Math.Max(1f, (float)Math.Round(data.CurrentInternalCorrosionFailures + RepairDefectFailureProbability * ((data.DefectNum ?? 0) - data.RepairedDefectNumbers), 1));
public void AssessmentTotalEquipmentRecovery(PrioritizationData data, DamageResult result)
var param1 = this.GetCosts1(data.OperatorName);
var param2 = this.GetCosts2(data.OperatorName);
var param3 = this.GetCosts3(data.OperatorName);
result.WithoutFillingLinePipelines = EquipmentRecovery(data, result.FailureNumber, PipelineTypeCode.line, param2.Item2);
result.WithoutFillingWaterCrossings = EquipmentRecovery(data, result.FailureNumber, PipelineTypeCode.water_crossings, param2.Item3);
result.WithoutFillingRailwayCrossing = EquipmentRecovery(data, result.FailureNumber, PipelineTypeCode.railway_crossing, param2.Item4);
result.WithoutFillingFederalRoadsCrossing = EquipmentRecovery(data, result.FailureNumber, PipelineTypeCode.federal_roads_crossing, param2.Item5);
result.WithFillingLinePipelines = EquipmentRecovery(data, result.FailureNumber, PipelineTypeCode.line, param2.Item6);
result.WithFillingWaterCrossings = EquipmentRecovery(data, result.FailureNumber, PipelineTypeCode.water_crossings, param2.Item7);
result.WithFillingRailwayCrossing = EquipmentRecovery(data, result.FailureNumber, PipelineTypeCode.railway_crossing, param3.Item1);
result.WithFillingFederalRoadsCrossing = EquipmentRecovery(data, result.FailureNumber, PipelineTypeCode.federal_roads_crossing, param3.Item2);
private static float EquipmentRecovery(PrioritizationData data, float FailureNumber, PipelineTypeCode ptype, float cost)
if (data.LayingPipeline == LayingPipelineCode.swamp)
return data.PipelineType == ptype ? cost * FailureNumber : 0f;
private static float LiquidLoss(float density_fraction, float Pin, float Pout, float liquid_density)
return (float)(1138 * density_fraction * (0.6 * 1.13 / 10000) * Math.Sqrt((Pin + Pout) / liquid_density));
private static float CrudeOilLoss(PrioritizationData data)
return LiquidLoss(data.OilDensity, data.InletPressure, data.OutletPressure, data.OilDensity);
private static float OilLoss(PrioritizationData data)
return LiquidLoss((1 - data.WaterCutValue / 100) * data.OilDensity, data.InletPressure, data.OutletPressure, 0.5f * (data.OilDensity + data.WaterDensity));
private static float OilShortage(float OilRate, float wc)
return (float)(0.0416 * OilRate * (1 - wc / 100) * 18);
private static float GasLoss(PrioritizationData data)
var square = 3.14 * Math.Pow(data.Diameter / 1000, 2) / 4;
var avg_pressure = (data.InletPressure + data.OutletPressure) / 2;
return (float)(square * data.Length * avg_pressure + (1065 * 1.13 / 10000) * avg_pressure);
public void AssessmentOilLoss(PrioritizationData data, DamageResult result)
switch (ToFluid(data.PurposePipeline))
case FluidType.production_oil:
result.MassOilLoss = OilLoss(data); break;
case FluidType.crude_oil:
result.MassOilLoss = CrudeOilLoss(data); break;
result.MassOilLoss *= data.PipelineType == PipelineTypeCode.water_crossings ? 4 : 6;
var param1 = GetCosts1(data.OperatorName);
result.OilLoss = result.MassOilLoss * param1.Item1;
public void AssessmentWaterLoss(PrioritizationData data, DamageResult result)
result.MassWaterLoss = 0;
switch (ToFluid(data.PurposePipeline))
case FluidType.fresh_water:
case FluidType.reservoir_water:
result.MassWaterLoss = LiquidLoss(data.WaterDensity, data.InletPressure, data.OutletPressure, data.WaterDensity); break;
result.WaterLoss *= data.PipelineType == PipelineTypeCode.water_crossings ? 4 : 6;
var param1 = GetCosts1(data.OperatorName);
result.WaterLoss = result.MassWaterLoss * param1.Item2;
public void AssessmentGasLoss(PrioritizationData data, DamageResult result)
result.VolumeGasLoss = 0;
if (ToFluid(data.PurposePipeline) == FluidType.gas)
result.VolumeGasLoss = GasLoss(data);
result.VolumeGasLoss *= data.PipelineType == PipelineTypeCode.water_crossings ? 4 : 6;
var param1 = GetCosts1(data.OperatorName);
result.GasLoss = result.VolumeGasLoss * param1.Item3;
public void AssessmentOilShortage(PrioritizationData data, DamageResult result)
result.MassOilShortage = 0f;
switch (ToFluid(data.PurposePipeline))
case FluidType.production_oil:
result.MassOilShortage = OilShortage(data.OilRate, data.WaterCutValue);
case FluidType.crude_oil:
result.MassOilShortage = OilShortage(data.OilRate, 0);
var param1 = GetCosts1(data.OperatorName);
result.OilShortage = result.MassOilShortage * param1.Item1;
public void AssessmentLandReclamationCosts(PrioritizationData data, DamageResult result)
switch(ToFluid(data.PurposePipeline))
case FluidType.crude_oil:
case FluidType.production_oil:
result.LandReclamationArea = result.MassOilLoss / data.OilDensity * 1000 * 5; break;
case FluidType.fresh_water:
case FluidType.reservoir_water:
result.LandReclamationArea = LiquidLoss(data.WaterDensity, data.InletPressure, data.OutletPressure, data.WaterDensity); break;
result.LandReclamationArea = 0; break;
result.LandReclamationCosts = result.LandReclamationArea *
(float)(data.PipelineType == PipelineTypeCode.water_crossings ? 0f : GetCosts1(data.OperatorName).Item4 * 1e-4);
public void AssessmentWaterBodiesRestorationCosts(PrioritizationData data, DamageResult result)
if (data.PipelineType == PipelineTypeCode.water_crossings)
result.WaterBodiesRestorationCosts = result.FailureNumber * result.MassOilLoss * GetCosts1(data.OperatorName).Item6;
else result.WaterBodiesRestorationCosts = 0f;
public void AssessmentTotalPenalties(PrioritizationData data, DamageResult result)
result.LandLaw_8_1 = data.PipelineType == PipelineTypeCode.water_crossings ? 0f : result.FailureNumber * GetPenlties().Item2;
var ldp = GetLandDamagePenalties(data.PurposePipelineCode);
result.Kish = GetLandDamagePenalties(data.LandCategory);
result.Tx = GetCosts2(data.OperatorName).Item1;
result.PotentialPenalty = data.PipelineType == PipelineTypeCode.water_crossings ? 0 : result.LandReclamationArea * result.CXB * result.Kg * result.Kish * result.Tx;
var fluid = ToFluid(data.PurposePipeline);
result.FactPenalty = fluid == FluidType.crude_oil || fluid == FluidType.production_oil || fluid == FluidType.reservoir_water ? result.PotentialPenalty : 0;
var ForestPenalty1 = GetForestPenalties().Item1;
var ForestPenalty2 = GetForestPenalties().Item2;
if (data.PipelineType == PipelineTypeCode.line && data.LandCategory == LandCategoryCode.forest_lands)
result.DamageForestedAreas = result.LandReclamationArea * GetCosts1(data.OperatorName).Item5 * ForestPenalty1 * ForestPenalty2 * GetCosts3(data.OperatorName).Item4;
else result.DamageForestedAreas = 0f;
result.TotalLandPenalty = result.LandLaw_8_1 + result.FactPenalty + result.DamageForestedAreas;
result.WaterBodyLaw_8_1 = data.PipelineType == PipelineTypeCode.water_crossings ? GetPenlties().Item3 * result.FailureNumber : 0;
result.Kvg = (float)(0.25*(1.15+1.25+1.1+1.15));
result.Kv = GetWaterBodyPenalties(data.WaterBodyLocation);
result.Kin = GetIndexingFactor();
result.Kdp = GetDurationFactor(data.FailoverPlanTime);
result.Tax = data.PipelineType == PipelineTypeCode.water_crossings ? GetWaterBodyTax(result.OilLoss) : 0;
result.DamageWaterBody = result.Kvg * result.Kv * result.Kin * result.Kdp * result.Tax;
result.WaterBodyPenalty = data.PipelineType == PipelineTypeCode.water_crossings ? result.WaterBodyLaw_8_1 + result.DamageWaterBody: 0;
var avg_pressure = (data.InletPressure + data.OutletPressure) / 2;
var gp = GetGasPenalties();
result.GasPenalty = result.VolumeGasLoss * avg_pressure * 1000 * gp.Item1 * gp.Item2;
result.TotalPenalties = result.TotalLandPenalty + result.WaterBodyPenalty + result.GasPenalty;
result.TotalDamage = (float)Math.Max(0.1, result.TotalEquipmentRecovery + result.OilLoss + result.WaterLoss +
result.GasLoss + result.OilShortage + result.LandReclamationCosts +
result.WaterBodiesRestorationCosts + result.TotalPenalties);
public static float GetAvgGasComponentFactor(FluidType fluid)
return (new Dictionary<FluidType, float>()
{FluidType.crude_oil, 0.75f},
{FluidType.production_oil, 0.75f},
{FluidType.reservoir_water, 0.9f},
{FluidType.fresh_water, 0.9f}
public ValueTuple<float, float> GetLandDamagePenalties(int purpose)
return (new Dictionary<int, ValueTuple<float, float>>()
}).ToCode(purpose, (6f, 1f));
public float GetLandDamagePenalties(LandCategoryCode land)
return (new Dictionary<LandCategoryCode, float>()
{ LandCategoryCode.industrial_lands, 1f },
{ LandCategoryCode.specially_protected_areas, 2f },
{ LandCategoryCode.mountain_pastures, 1.9f },
{ LandCategoryCode.water_protection_zones, 1.8f },
{ LandCategoryCode.agricultural, 1.6f },
{ LandCategoryCode.forest_lands, 1.5f },
{ LandCategoryCode.settlement_lands, 1.3f },
{ LandCategoryCode.industrial_designation_zone, 1f },
{ LandCategoryCode.special_purpose_zone, 1f },
{ LandCategoryCode.engineering_and_transport_infrastructures_zone, 1f },
{ LandCategoryCode.military_objects_zone, 1f },
{ LandCategoryCode.other, 1f },
public float GetWaterBodyPenalties(string location)
return (new Dictionary<string, float>()
{" Нева и притоки", 1.51f },
{" Неман и притоки", 1.21f },
{" Реки бассейна Ладожского озера", 2.1f },
{" Реки бассейна Онежского озера", 2.1f },
{" Реки бассейна озера Ильмень", 2.1f },
{" Реки бассейна Балтийского моря", 1.18f },
{" Северная Двина и притоки", 1.36f },
{" Реки бассейна Белого моря", 1.16f },
{" Печора и притоки", 1.37f },
{" Реки бассейна Баренцева моря", 1.22f },
{" Волга и притоки", 1.41f },
{" Терек и притоки", 1.55f },
{" Урал и притоки", 1.6f },
{" Сулак, Самур и притоки", 1.45f },
{" Реки бассейна Каспийского моря", 1.39f },
{" Дон и притоки", 1.29f },
{" Кубань и притоки", 2.2f },
{" Реки бассейна Азовского моря", 1.64f },
{" Днепр и притоки", 1.33f },
{" Реки бассейна Черного моря", 1.95f },
{" Обь и притоки", 1.22f },
{" Енисей и притоки", 1.36f },
{" Реки бассейна Карского моря", 1.23f },
{" Лена и притоки", 1.27f },
{" Реки бассейна озера Байкал", 2.8f },
{" Реки бассейна моря Лаптевых", 1.18f },
{" Реки бассейна Восточно-Сибирского моря", 1.15f },
{" Реки бассейна Чукотского моря", 1.12f },
{" Реки бассейна Берингова моря", 1.12f },
{" Амур и притоки", 1.27f },
{" Реки бассейна Охотского моря", 1.32f },
{" Реки бассейна Японского моря", 1.32f },
{" Реки бассейна Тихого океана", 1.2f },
{" Озеро Ладожское", 2.1f },
{" Озеро Ильмень", 2.1f },
{" Озеро Онежское", 2.1f },
{" Озеро Байкал", 2.8f },
{" Озера прочие", 1.8f },
{" Акватория Азовского моря", 1.25f },
{" Акватория Каспийского моря", 1.25f },
{" Акватория Черного моря", 1.15f },
{" Акватория Балтийского моря", 1.05f },
{" Акватория Белого моря", 1.05f },
{" Акватория Баренцевого моря", 1.05f },
{" Акватория Японского моря", 1.05f },
{" Акватория Карского моря", 1.02f },
{" Акватория Берингова моря", 1.02f },
{" Акватория Охотского моря", 1.02f },
{" Акватория моря Лаптевых", 1f },
{" Акватория Восточно-Сибирского моря", 1f },
{" Акватория Чукотского моря", 1f },
{" Акватория Тихого океана", 1.02f },
{" Другие водные объекты", 0.85f }
}).ToCode(location, 0.85f);
public float GetDurationFactor(FailoverPlanTimeCode time)
return (new Dictionary<FailoverPlanTimeCode, float>()
{ FailoverPlanTimeCode.l6, 1.1f },
{ FailoverPlanTimeCode.l12, 1.2f },
{ FailoverPlanTimeCode.l18, 1.3f },
{ FailoverPlanTimeCode.l24, 1.4f },
{ FailoverPlanTimeCode.l30, 1.5f },
{ FailoverPlanTimeCode.l36, 1.6f },
{ FailoverPlanTimeCode.l48, 1.7f },
{ FailoverPlanTimeCode.l60, 1.8f },
{ FailoverPlanTimeCode.l72, 1.9f },
{ FailoverPlanTimeCode.l84, 2f },
{ FailoverPlanTimeCode.l96, 2.1f },
{ FailoverPlanTimeCode.l108, 2.2f },
{ FailoverPlanTimeCode.l120, 2.3f },
{ FailoverPlanTimeCode.l132, 2.4f },
{ FailoverPlanTimeCode.g132, 2.4f }
public float GetWaterBodyTax(float loss)
var intervals = new float [] { 0, 0,01, 0,25, 0,5, 1, 2,5, 5, 10, 20, 35, 50, 90, 160, 400, 600, 800, 1300, 2000, 3500, 5000 };
var taxes = new float [] { 0, 0,6, 1, 1,4, 2,3, 3,7, 6,1, 11, 22, 28, 52, 84, 229, 349, 464, 574, 840, 1344, 2016, 2016 };
return taxes[intervals.IntervalIndex(loss)];
public class PrioritizationFileDataExt : PrioritizationFileData
public class AssessmentFactors
public enum OperatorNameCode
Sakhalinmorneftegaz = 17,
public enum LandCategoryCode
specially_protected_areas = 2,
water_protection_zones = 4,
industrial_designation_zone = 8,
special_purpose_zone = 9,
engineering_and_transport_infrastructures_zone = 10,
military_objects_zone = 11,
public enum FailoverPlanTimeCode
public enum LayingPipelineCode
public_attention_area = 4,
private_property_lands = 5,
ravines_streams_crossing = 8,
public enum PipelineTypeCode
federal_roads_crossing = 4