public GridDefinitionAnalysis(IDataStorageDefinition storageDef, string latArrayName = null, string lonArrayName = null)
        {
            if (string.IsNullOrEmpty(latArrayName))
            {
                latArrayName = IntegratorsFactoryHelpers.AutodetectLatName(storageDef);
            }
            if (string.IsNullOrEmpty(lonArrayName))
            {
                lonArrayName = IntegratorsFactoryHelpers.AutodetectLonName(storageDef);
            }

            missingValuesDictionary = new MissingValuesDictionary(storageDef);
            dimensionOrderDictioary = new Dictionary <string, DimensionsOrder>();
            Dictionary <string, int> ranks = new Dictionary <string, int>();

            variableRankDict = ranks;

            var dataVarsNames = storageDef.VariablesDimensions //looking schema for 2D and 3D data arrays
                                .Where(def =>
                                       (def.Value.Contains(storageDef.VariablesDimensions[latArrayName][0]) &&
                                        def.Value.Contains(storageDef.VariablesDimensions[lonArrayName][0]) && (def.Key != latArrayName) && (def.Key != lonArrayName)))
                                .Select(def => def.Key).ToArray();

            //analyzing data variables
            foreach (var dataVarName in dataVarsNames)
            {
                //analyzing dimensions
                dimensionOrderDictioary[dataVarName] = DetermineDimensionsOrder(storageDef, latArrayName, lonArrayName, dataVarName);
                ranks[dataVarName] = storageDef.VariablesDimensions[dataVarName].Length;
            }
        }
        public static async Task <NCEPReanalysisRegularGridDataHandler> CreateAsync(IStorageContext dataContext)
        {
            var storageDefinition = dataContext.StorageDefinition;
            var timeAxis          = await dataContext.GetDataAsync("time");

            var timeIntegrator = new TimeAxisAvgProcessing.TimeAxisAvgFacade(
                timeAxis,
                new TimeAxisProjections.ContinuousHours(new DateTime(1, 1, 1)),
                new WeightProviders.LinearInterpolation(),
                new DataCoverageEvaluators.IndividualObsCoverageEvaluator());
            var latIntegratorTask = LinearIntegratorsFactory.SmartConstructAsync(dataContext, IntegratorsFactoryHelpers.AutodetectLatName(storageDefinition));
            var lonIntegratorTask = LinearIntegratorsFactory.SmartConstructAsync(dataContext, IntegratorsFactoryHelpers.AutodetectLonName(storageDefinition));

            var latIntegrator = await latIntegratorTask;
            var lonIntegrator = await lonIntegratorTask;

            var thinningTimeIntegrator = new TimeAxisIntegratorThinningDecorator(timeIntegrator);
            var thinningLatIntegrator  = new SpatGridIntegatorThinningDecorator(latIntegrator);
            var thinningLonIntegrator  = new SpatGridIntegatorThinningDecorator(lonIntegrator);

            var baseNodeUncertainty         = new NoBaseUncertaintyProvider();
            var temporalVarianceCalculaator = new LinearCombination1DVarianceCalc(new StorageContextMetadataTimeVarianceExtractor(storageDefinition), timeIntegrator);
            var spatialVarianceCalculator   = new LinearCombinationOnSphereVarianceCalculator(new StorageContextMetadataSpatialVarianceExtractor(storageDefinition), latIntegrator, lonIntegrator);

            var gaussianFieldUncertaintyEvaluator = new SequentialTimeSpatialUncertaintyEvaluatorFacade(thinningTimeIntegrator, thinningLatIntegrator, thinningLonIntegrator, temporalVarianceCalculaator, spatialVarianceCalculator, baseNodeUncertainty);
            var coverageCheckUncertaintyEvaluator = new GridUncertaintyConventionsDecorator(gaussianFieldUncertaintyEvaluator, latIntegrator, lonIntegrator, timeIntegrator); //we do not need DegK to DegC in uncertainty as uncertainty is based on defference and does not depend on constant ofsets
            var variablePresenceCheckEvaluator    = new VariablePresenceCheckDecorator(dataContext.StorageDefinition, coverageCheckUncertaintyEvaluator);

            var gridAggregator       = new GridMeanAggregator(dataContext, timeIntegrator, latIntegrator, lonIntegrator, false);
            var clusteringAggregator = new GridClusteringDecorator(dataContext.StorageDefinition, gridAggregator, timeIntegrator, latIntegrator, lonIntegrator);
            var scaledAggregator     = new Microsoft.Research.Science.FetchClimate2.ValueAggregators.LinearTransformDecorator(dataContext, clusteringAggregator);

            scaledAggregator.SetAdditionalTranform("air", new Func <double, double>(v => v - 273.15)); // DegK to DegC

            return(new NCEPReanalysisRegularGridDataHandler(dataContext, variablePresenceCheckEvaluator, scaledAggregator));
        }
        public static async Task <NCEPReanalysisGaussT62GridDataHandler> CreateAsync(IStorageContext dataContext)
        {
            var storageDefinition = dataContext.StorageDefinition;
            var timeAxis          = await dataContext.GetDataAsync("time");

            var timeIntegrator = new TimeAxisAvgProcessing.TimeAxisAvgFacade(
                timeAxis,
                new TimeAxisProjections.ContinuousHours(new DateTime(1, 1, 1)),
                new WeightProviders.StepFunctionInterpolation(),
                new DataCoverageEvaluators.ContinousMeansCoverageEvaluator());
            var latIntegratorTask = LinearIntegratorsFactory.SmartConstructAsync(dataContext, IntegratorsFactoryHelpers.AutodetectLatName(storageDefinition));
            var lonIntegratorTask = LinearIntegratorsFactory.SmartConstructAsync(dataContext, IntegratorsFactoryHelpers.AutodetectLonName(storageDefinition));


            var latIntegrator = await latIntegratorTask;
            var lonIntegrator = await lonIntegratorTask;

            var thinningTimeIntegrator = new TimeAxisIntegratorThinningDecorator(timeIntegrator);
            var thinningLatIntegrator  = new SpatGridIntegatorThinningDecorator(latIntegrator);
            var thinningLonIntegrator  = new SpatGridIntegatorThinningDecorator(lonIntegrator);

            var baseNodeUncertainty         = new NoBaseUncertaintyProvider();
            var temporalVarianceCalculaator = new LinearCombination1DVarianceCalc(new StorageContextMetadataTimeVarianceExtractor(storageDefinition), timeIntegrator);
            var spatialVarianceCalculator   = new LinearCombinationOnSphereVarianceCalculator(new StorageContextMetadataSpatialVarianceExtractor(storageDefinition), latIntegrator, lonIntegrator);

            var gaussianFieldUncertaintyEvaluator = new SequentialTimeSpatialUncertaintyEvaluatorFacade(thinningTimeIntegrator, latIntegrator, lonIntegrator, temporalVarianceCalculaator, spatialVarianceCalculator, baseNodeUncertainty);
            var coverageCheckUncertaintyEvaluator = new GridUncertaintyConventionsDecorator(gaussianFieldUncertaintyEvaluator, latIntegrator, lonIntegrator, timeIntegrator);
            var scaledUncertaintyEvaluator        = new Microsoft.Research.Science.FetchClimate2.UncertaintyEvaluators.LinearTransformDecorator(coverageCheckUncertaintyEvaluator);
            var variablePresenceCheckEvaluator    = new VariablePresenceCheckDecorator(dataContext.StorageDefinition, scaledUncertaintyEvaluator);

            scaledUncertaintyEvaluator.SetTranform("prate", new Func <double, double>(v => v * 2592000.0)); //kg/m^2/s to mm/month (assuming month is 30 days)

            var gridAggregator       = new GridMeanAggregator(dataContext, timeIntegrator, latIntegrator, lonIntegrator, false);
            var clusteringAggregator = new GridClusteringDecorator(dataContext.StorageDefinition, gridAggregator, timeIntegrator, latIntegrator, lonIntegrator);
            var scaledAggregator     = new Microsoft.Research.Science.FetchClimate2.ValueAggregators.LinearTransformDecorator(dataContext, clusteringAggregator);

            scaledAggregator.SetAdditionalTranform("prate", new Func <double, double>(v => v * 2592000.0)); //kg/m^2/s to mm/month (assuming month is 30 days)

            return(new NCEPReanalysisGaussT62GridDataHandler(dataContext, variablePresenceCheckEvaluator, scaledAggregator));
        }
        public static async Task <WorldClim14DataSource> CreateAsync(IStorageContext dataContext)
        {
            var storageDefinition = dataContext.StorageDefinition;
            var latIntegratorTask = LinearIntegratorsFactory.SmartConstructAsync(dataContext, IntegratorsFactoryHelpers.AutodetectLatName(storageDefinition));
            var lonIntegratorTask = LinearIntegratorsFactory.SmartConstructAsync(dataContext, IntegratorsFactoryHelpers.AutodetectLonName(storageDefinition));

            var timeIntegrator = new TimeAxisAvgProcessing.MonthlyMeansOverEnoughYearsStepIntegratorFacade(50); // http://www.worldclim.org/methods says: "in most cases these records will represent the 1950-2000"
            var latIntegrator  = await latIntegratorTask;
            var lonIntegrator  = await lonIntegratorTask;

            var thinningLatIntegrator = new SpatGridIntegatorThinningDecorator(latIntegrator);
            var thinningLonIntegrator = new SpatGridIntegatorThinningDecorator(lonIntegrator);

            var baseNodeUncertainty         = new WorldClimBaseNodeUnceratinty();
            var temporalVarianceCalculaator = new LinearCombination1DVarianceCalc(new StorageContextMetadataTimeVarianceExtractor(storageDefinition, 12.0), timeIntegrator);
            var spatialVarianceCalculator   = new LinearCombinationOnSphereVarianceCalculator(new StorageContextMetadataSpatialVarianceExtractor(storageDefinition), latIntegrator, lonIntegrator);


            var bitMaskProvider = new EmbeddedResourceBitMaskProvider(typeof(WorldClim14DataSource), "Microsoft.Research.Science.FetchClimate2.WcDataMask.bf");

            var gaussianFieldUncertaintyEvaluator   = new SequentialTimeSpatialUncertaintyEvaluatorFacade(timeIntegrator, thinningLatIntegrator, thinningLonIntegrator, temporalVarianceCalculaator, spatialVarianceCalculator, baseNodeUncertainty);
            var coverageCheckUncertaintyEvaluator   = new GridUncertaintyConventionsDecorator(gaussianFieldUncertaintyEvaluator, latIntegrator, lonIntegrator, timeIntegrator);
            var landMaskEnabledUncertaintyEvaluator = new GridBitmaskDecorator(coverageCheckUncertaintyEvaluator, bitMaskProvider);
            var variablePresenceCheckEvaluator      = new VariablePresenceCheckDecorator(dataContext.StorageDefinition, landMaskEnabledUncertaintyEvaluator);

            var gridAggregator       = new GridMeanAggregator(dataContext, timeIntegrator, latIntegrator, lonIntegrator, true);
            var clusteringAggregator = new GridClusteringDecorator(dataContext.StorageDefinition, gridAggregator, timeIntegrator, latIntegrator, lonIntegrator);
            var scaledAggregator     = new Microsoft.Research.Science.FetchClimate2.ValueAggregators.LinearTransformDecorator(dataContext, clusteringAggregator);

            return(new WorldClim14DataSource(dataContext, variablePresenceCheckEvaluator, scaledAggregator));
        }