Пример #1
0
        IReadOnlyCollection <Panel> ValidatePanels(PanelValidationContext ctx)
        {
            var validated = new List <Panel>();

            foreach (var panel in ctx.Allowed)
            {
                var itemCount = panel.SubPanels.SelectMany(x => x.PanelItems).Count();
                if (itemCount == 0)
                {
                    continue;
                }

                CheckDateFilter(panel);

                var validatedSubs = new List <SubPanel>();
                foreach (var subpanel in panel.SubPanels)
                {
                    if (subpanel.PanelItems.Any())
                    {
                        subpanel.PanelIndex = panel.Index;
                        foreach (var panelItem in subpanel.PanelItems)
                        {
                            panelItem.SubPanelIndex = subpanel.Index;
                            panelItem.PanelIndex    = panel.Index;
                        }
                        validatedSubs.Add(subpanel);
                    }
                }
                panel.SubPanels = validatedSubs;

                validated.Add(panel);
            }

            return(validated);
        }
Пример #2
0
        void ValidateItems(PanelValidationContext ctx)
        {
            var zipped = ZipContextItems(ctx);

            foreach (var mapping in zipped)
            {
                EnsureSpecializationAlignment(mapping);
                EnsureValidRecencyFilter(mapping);
                EnsureValidNumericFilter(mapping);
            }
        }
Пример #3
0
        // NOTE(cspital) at this point, we are certain the counts are the same.
        IEnumerable <PanelItemMapping> ZipContextItems(PanelValidationContext ctx)
        {
            var dtos = ctx.Requested
                       .SelectMany(p => p.SubPanels)
                       .SelectMany(s => s.PanelItems)
                       .ToArray();

            var mods = ctx.Allowed
                       .SelectMany(p => p.SubPanels)
                       .SelectMany(s => s.PanelItems)
                       .ToArray();

            return(dtos.Zip(mods, (dto, mod) => new PanelItemMapping(dto, mod)));
        }
Пример #4
0
        public PatientCountQuery Validate(PanelValidationContext ctx)
        {
            if (!ctx.PreflightPassed)
            {
                throw new InvalidOperationException("PreflightCheck failed, nothing to validate.");
            }
            ValidateItems(ctx);
            var panels = ValidatePanels(ctx);

            return(new PatientCountQuery
            {
                QueryId = ctx.QueryId,
                Panels = panels
            });
        }
Пример #5
0
        public void Obfuscate(ref PatientCount count, PanelValidationContext ctx, DeidentificationOptions opts)
        {
            if (!opts.Cohort.Enabled)
            {
                return;
            }

            // If low cell sizes should be masked and count less than or equal to threshold, set to threshold.
            if (opts.Cohort.LowCellSizeMasking.Enabled && count.Value <= opts.Cohort.LowCellSizeMasking.Threshold)
            {
                count.Value     = opts.Cohort.LowCellSizeMasking.Threshold;
                count.PlusMinus = opts.Cohort.LowCellSizeMasking.Threshold;
                count.WithinLowCellThreshold = true;
                return;
            }

            // Bail if noise obfuscation not enabled
            if (!opts.Cohort.Noise.Enabled)
            {
                return;
            }

            // Ensure that variations of the same query (with concepts and panels moved around but the query logic identical)
            // always returns the same string of Guid Ids for concepts.
            var orderedIds = GetDeterministicConceptIdsAsString(ctx.Allowed);

            // Hash into a byte array.
            var hashed = md5.ComputeHash(Encoding.UTF8.GetBytes(orderedIds));

            // Seed a random number generator from the hash.
            var generator = new Random(BitConverter.ToInt32(hashed, 0));

            // Compute a random shifted value between the lower and upper bounds
            var shift = 0;

            while (shift == 0)
            {
                shift = generator.Next(opts.Cohort.Noise.LowerBound, opts.Cohort.Noise.UpperBound);
            }

            count.Value    += shift;
            count.PlusMinus = Math.Max(Math.Abs(opts.Cohort.Noise.LowerBound), Math.Abs(opts.Cohort.Noise.UpperBound));
        }