/// <summary> /// Calculation method. /// </summary> /// <param name="chainCharacteristicsIds"> /// Dictionary with chain ids as a key /// and characteristicLink ids array as value. /// </param> /// <returns> /// The <see cref="T:double[][]"/>. /// </returns> public static Dictionary <long, Dictionary <short, double> > Calculate(Dictionary <long, short[]> chainCharacteristicsIds) { var newCharacteristics = new List <CharacteristicValue>(); var allCharacteristics = new Dictionary <long, Dictionary <short, double> >(); using (var db = new LibiadaWebEntities()) { short[] characteristicLinkIds = chainCharacteristicsIds.SelectMany(c => c.Value).Distinct().ToArray(); var characteristicTypeLinkRepository = FullCharacteristicRepository.Instance; var calculators = new Dictionary <short, LinkedFullCalculator>(); foreach (short characteristicLinkId in characteristicLinkIds) { Link link = characteristicTypeLinkRepository.GetLinkForCharacteristic(characteristicLinkId); FullCharacteristic characteristic = characteristicTypeLinkRepository.GetCharacteristic(characteristicLinkId); calculators.Add(characteristicLinkId, new LinkedFullCalculator(characteristic, link)); } var commonSequenceRepository = new CommonSequenceRepository(db); long[] sequenceIds = chainCharacteristicsIds.Keys.ToArray(); foreach (long sequenceId in sequenceIds) { short[] sequenceCharacteristicLinkIds = chainCharacteristicsIds[sequenceId]; Dictionary <short, double> characteristics = db.CharacteristicValue .Where(c => sequenceId == c.SequenceId && sequenceCharacteristicLinkIds.Contains(c.CharacteristicLinkId)) .ToDictionary(ct => ct.CharacteristicLinkId, ct => ct.Value); allCharacteristics.Add(sequenceId, characteristics); if (characteristics.Count < sequenceCharacteristicLinkIds.Length) { Chain sequence = commonSequenceRepository.GetLibiadaChain(sequenceId); foreach (short sequenceCharacteristicLinkId in sequenceCharacteristicLinkIds) { if (!characteristics.ContainsKey(sequenceCharacteristicLinkId)) { LinkedFullCalculator calculator = calculators[sequenceCharacteristicLinkId]; double characteristicValue = calculator.Calculate(sequence); var characteristic = new CharacteristicValue { SequenceId = sequenceId, CharacteristicLinkId = sequenceCharacteristicLinkId, Value = characteristicValue }; characteristics.Add(sequenceCharacteristicLinkId, characteristicValue); newCharacteristics.Add(characteristic); } } } } var characteristicRepository = new CharacteristicRepository(db); characteristicRepository.TrySaveCharacteristicsToDatabase(newCharacteristics); return(allCharacteristics); } }
/// <summary> /// Calculates subsequences characteristics. /// </summary> /// <param name="characteristicIds"> /// The ids of characteristic types, arrangement types and links as <see cref="FullCharacteristicLink"/>. /// </param> /// <param name="features"> /// The features ids of subsequences to extract. /// </param> /// <param name="parentSequenceId"> /// The parent sequence id. /// </param> /// <param name="filters"> /// Textual search filters for subsequences products. /// </param> /// <returns> /// The <see cref="T:SubsequenceData[]"/> . /// </returns> public static SubsequenceData[] CalculateSubsequencesCharacteristics( short[] characteristicIds, Feature[] features, long parentSequenceId, string[] filters = null) { Dictionary <long, Chain> sequences; long[] subsequenceIds; SubsequenceData[] subsequenceData; Dictionary <long, Dictionary <short, double> > characteristics; var calculators = new IFullCalculator[characteristicIds.Length]; var links = new Link[characteristicIds.Length]; var newCharacteristics = new List <CharacteristicValue>(); // creating local context to avoid memory overflow due to possibly big cache of characteristics using (var db = new LibiadaWebEntities()) { var subsequenceExtractor = new SubsequenceExtractor(db); Subsequence[] subsequences = filters == null? subsequenceExtractor.GetSubsequences(parentSequenceId, features) : subsequenceExtractor.GetSubsequences(parentSequenceId, features, filters); subsequenceData = subsequences.Select(s => new SubsequenceData(s)).ToArray(); // converting to libiada sequences subsequenceIds = subsequences.Select(s => s.Id).ToArray(); characteristics = db.CharacteristicValue .Where(c => characteristicIds.Contains(c.CharacteristicLinkId) && subsequenceIds.Contains(c.SequenceId)) .ToArray() .GroupBy(c => c.SequenceId) .ToDictionary(c => c.Key, c => c.ToDictionary(ct => ct.CharacteristicLinkId, ct => ct.Value)); if (characteristics.Count == subsequences.Length && characteristics.All(c => c.Value.Count == characteristicIds.Length)) { sequences = new Dictionary <long, Chain>(); } else { sequences = subsequenceExtractor.GetSubsequencesSequences(subsequences); } } var characteristicTypeLinkRepository = FullCharacteristicRepository.Instance; for (int k = 0; k < characteristicIds.Length; k++) { short characteristicLinkId = characteristicIds[k]; FullCharacteristic characteristic = characteristicTypeLinkRepository.GetCharacteristic(characteristicLinkId); calculators[k] = FullCalculatorsFactory.CreateCalculator(characteristic); links[k] = characteristicTypeLinkRepository.GetLinkForCharacteristic(characteristicLinkId); } // cycle through subsequences for (int i = 0; i < subsequenceIds.Length; i++) { characteristics.TryGetValue(subsequenceIds[i], out Dictionary <short, double> sequenceDbCharacteristics); sequenceDbCharacteristics = sequenceDbCharacteristics ?? new Dictionary <short, double>(); var values = new double[calculators.Length]; // cycle through characteristics and notations for (int j = 0; j < calculators.Length; j++) { short characteristicLinkId = characteristicIds[j]; if (!sequenceDbCharacteristics.TryGetValue(characteristicLinkId, out values[j])) { values[j] = calculators[j].Calculate(sequences[subsequenceIds[i]], links[j]); var currentCharacteristic = new CharacteristicValue { SequenceId = subsequenceIds[i], CharacteristicLinkId = characteristicLinkId, Value = values[j] }; newCharacteristics.Add(currentCharacteristic); } } subsequenceData[i].CharacteristicsValues = values; } using (var db = new LibiadaWebEntities()) { // trying to save calculated characteristics to database var characteristicRepository = new CharacteristicRepository(db); characteristicRepository.TrySaveCharacteristicsToDatabase(newCharacteristics); } return(subsequenceData); }