/// <summary> /// Calculates the Percentiles [0;1] of an Item. MaxEntriesInMemory is used to reduce the memory consumption by sweeping multiple times. Units is MB of memory /// </summary> public void Percentile(int Item, int[] TSteps, DFSBase df, double[] Percentiles, int MaxEntriesInMemory) { //List counts percentiles float[][] OutData = new float[Percentiles.Count()][]; for (int i = 0; i < Percentiles.Count(); i++) { OutData[i] = new float[dfsdata.Count()]; } List <int> steps = new List <int>(); steps.Add(0); //Get the delete values float delete = DfsDLLWrapper.dfsGetDeleteValFloat(_headerPointer); //Read first time step and create a list with the indeces of non-delete values ReadItemTimeStep(0, Item); List <int> NonDeleteEntries = new List <int>(); for (int i = 0; i < dfsdata.Length; i++) { if (dfsdata[i] != delete) { NonDeleteEntries.Add(i); } } //Find out how many sweeps are necessary to not exceed max memory double TotalData = (double)NonDeleteEntries.Count * (double)TSteps.Count(); if (TotalData > (MaxEntriesInMemory * 40000)) { int nsteps = (int)Math.Max(TotalData / (MaxEntriesInMemory * 40000), 1); int StepLength = NonDeleteEntries.Count() / nsteps; for (int i = 0; i < nsteps; i++) { steps.Add(steps.Last() + StepLength); } } steps.Add(NonDeleteEntries.Count); //Now start the loop for (int m = 0; m < steps.Count - 1; m++) { int dfscount = steps[m + 1] - steps[m]; //First iterater is dfsdata float[][] Data = new float[dfscount][]; for (int i = 0; i < Data.Count(); i++) { Data[i] = new float[TSteps.Count()]; } //Collect all data for (int i = 0; i < TSteps.Count(); i++) { var data = ReadItemTimeStep(TSteps[i], Item); int local = 0; for (int k = steps[m]; k < steps[m + 1]; k++) { Data[local][i] = (dfsdata[NonDeleteEntries[k]]); local++; } } int local2 = 0; for (int k = steps[m]; k < steps[m + 1]; k++) { //Convert to doubles from float double[] ddata = new double[TSteps.Count()]; for (int n = 0; n < TSteps.Count(); n++) { ddata[n] = Data[local2][n]; } //Calculate the percentile MathNet.Numerics.Statistics.Percentile pCalc = new MathNet.Numerics.Statistics.Percentile(ddata); pCalc.Method = MathNet.Numerics.Statistics.PercentileMethod.Excel; var p = pCalc.Compute(Percentiles); for (int l = 0; l < Percentiles.Count(); l++) { OutData[l][NonDeleteEntries[k]] = (float)p[l]; } local2++; } } //Insert deletevalues in output data for (int i = 0; i < dfsdata.Length; i++) { if (!NonDeleteEntries.Contains(i)) { for (int l = 0; l < Percentiles.Count(); l++) { OutData[l][i] = delete; } } } //Set Item infor for (int i = 0; i < Percentiles.Count(); i++) { df.Items[i].EumItem = Items[Item - 1].EumItem; df.Items[i].EumUnit = Items[Item - 1].EumUnit; df.Items[i].Name = Percentiles[i].ToString() + " percentile"; } for (int i = 0; i < Percentiles.Count(); i++) { df.WriteItemTimeStep(0, i + 1, OutData[i]); } }
public int ReadDfsFile(string dfsFileName) { int rc; DfsDLLWrapper.dfsFileRead(dfsFileName, out pHeader, out pFile); m_fileName = dfsFileName; compressed = (DfsDLLWrapper.dfsIsFileCompressed(pHeader)); if (compressed) { encodeKeySize = DfsDLLWrapper.dfsGetEncodeKeySize(pHeader); if (encodeKeySize > 0) { compress_XKey = new int[encodeKeySize]; compress_YKey = new int[encodeKeySize]; compress_ZKey = new int[encodeKeySize]; DfsDLLWrapper.dfsGetEncodeKey(pHeader, compress_XKey, compress_YKey, compress_ZKey); } else { compressed = false; } } // general info about file dfsFileType = (FileType)DfsDLLWrapper.dfsGetFileType(pHeader); DataType = DfsDLLWrapper.dfsGetDataType(pHeader); //delete value delVal = DfsDLLWrapper.dfsGetDeleteValFloat(pHeader); //statisics type statType = DfsDLLWrapper.dfsGetItemStatsType(pHeader); //Custom blocks DfsSimpleType iDataType = DfsSimpleType.Float; int iMiscVarNos = 0; IntPtr pData = pHeader; IntPtr pNextBlock = pHeader; IntPtr pBlock = pHeader; pBlock = DfsDLLWrapper.dfsGetCustomBlockRef(pHeader); if (pBlock.ToInt32() != 0) { DfsDLLWrapper.dfsGetCustomBlock(pBlock, out iDataType, out CustomBlockName, out iMiscVarNos, ref pData, out pNextBlock); switch ((DfsSimpleType)iDataType) { case DfsSimpleType.Float: custBlockDataFloat = new float[iMiscVarNos]; Marshal.Copy(pData, custBlockDataFloat, 0, custBlockDataFloat.Length); // copy data from pointer to array break; case DfsSimpleType.Int: custBlockDataInt = new int[iMiscVarNos]; Marshal.Copy(pData, custBlockDataInt, 0, custBlockDataInt.Length); // copy data from pointer to array break; default: throw new Exception("Unsupported CustomBlock data tyoe encountered (" + iDataType + "."); } if (CustomBlockName == "MIKE_FM") { //dfsu if (custBlockDataInt.Length > 0) { dfsuCustBlock.NoNodesTot = custBlockDataInt[0]; } if (custBlockDataInt.Length > 1) { dfsuCustBlock.NoElemTot = custBlockDataInt[1]; } if (custBlockDataInt.Length > 2) { dfsuCustBlock.Dim = custBlockDataInt[2]; } if (custBlockDataInt.Length > 3) { dfsuCustBlock.NoLayers = custBlockDataInt[3]; } } else if (CustomBlockName == "M21_Misc") { if (custBlockDataFloat.Length > 0) { m21CustBlock.ori = custBlockDataFloat[0]; //m_LITOrientation } if (custBlockDataFloat.Length > 1) { m21CustBlock.f1 = custBlockDataFloat[1]; } if (custBlockDataFloat.Length > 2) { m21CustBlock.f2 = custBlockDataFloat[2]; } if (custBlockDataFloat.Length > 3) { m21CustBlock.f3 = custBlockDataFloat[3]; //m_LandValue } if (custBlockDataFloat.Length > 4) { m21CustBlock.f4 = custBlockDataFloat[4]; } if (custBlockDataFloat.Length > 5) { m21CustBlock.f5 = custBlockDataFloat[5]; } if (custBlockDataFloat.Length > 6) { m21CustBlock.f6 = custBlockDataFloat[6]; //m_GISLITOrientation } } } //time axis tAxisType = (TimeAxisType)DfsDLLWrapper.dfsGetTimeAxisType(pHeader); switch (tAxisType) { case TimeAxisType.CalendarEquidistant: DfsDLLWrapper.dfsGetEqCalendarAxis(pHeader, out tAxis_StartDateStr, out tAxis_StartTimeStr, out tAxis_EUMUnit, out tAxis_EUMUnitStr, out tAxis_dTStart, out tAxis_dTStep, out tAxis_nTSteps, out tAxis_indexTStart); break; case TimeAxisType.Undefined: DfsDLLWrapper.dfsGetEqCalendarAxis(pHeader, out tAxis_StartDateStr, out tAxis_StartTimeStr, out tAxis_EUMUnit, out tAxis_EUMUnitStr, out tAxis_dTStart, out tAxis_dTStep, out tAxis_nTSteps, out tAxis_indexTStart); break; case TimeAxisType.CalendarNonEquidistant: DfsDLLWrapper.dfsGetNeqCalendarAxis(pHeader, out tAxis_StartDateStr, out tAxis_StartTimeStr, out tAxis_EUMUnit, out tAxis_EUMUnitStr, out tAxis_dTStart, out tAxis_dTStep, out tAxis_nTSteps, out tAxis_indexTStart); break; case TimeAxisType.TimeEquidistant: DfsDLLWrapper.dfsGetEqTimeAxis(pHeader, out tAxis_EUMUnit, out tAxis_EUMUnitStr, out tAxis_dTStart, out tAxis_dTStep, out tAxis_nTSteps, out tAxis_indexTStart); break; case TimeAxisType.TimeNonEquidistant: DfsDLLWrapper.dfsGetNeqTimeAxis(pHeader, out tAxis_EUMUnit, out tAxis_EUMUnitStr, out tAxis_dTStart, out tAxis_dTStep, out tAxis_nTSteps, out tAxis_indexTStart); break; default: return(_err(tAxisType.ToString() + " not supported")); } //Projection Projection_type = (ProjectionType)DfsDLLWrapper.dfsGetGeoInfoType(pHeader); if (Projection_type == ProjectionType.Projection) { DfsDLLWrapper.dfsGetGeoInfoUTMProj(pHeader, out Projection, out Longitude, out Latitude, out Orientation); } //Dynamic Items int ItemCount = DfsDLLWrapper.dfsGetNoOfItems(pHeader); Items = new DfsItemInfo[ItemCount]; for (int i = 1; i < Items.Length + 1; i++) { Items[i - 1] = new DfsItemInfo(); Items[i - 1].fileInfoRef = this; Items[i - 1].Read(i); // reads header } //Static Items rc = 0; int sItemNo = 0; while (true) { sItemNo++; try { DfsDLLWrapper.dfsFindItemStatic(pHeader, pFile, sItemNo); } catch { break; }// no more static items } if (sItemNo > 0) { staticItems = new DfsItemInfo[sItemNo - 2]; for (int i = 0; i < staticItems.Length; i++) { staticItems[i] = new DfsItemInfo(); staticItems[i].fileInfoRef = this; rc = staticItems[i].ReadStatic(i + 1); // read header } if (readStaticDataOnRead) { rc = ReadStaticData(); } } return(rc); }