using NUnit.Framework; using NUnit.Framework.Internal; using Strata.RxNorm.Biz.RxNorm; using Strata.RxNorm.Biz.RxNorm.Dimensions; using Strata.RxNorm.Biz.Test.Unit.Extensions; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using VerifyNUnit; using VerifyTests; namespace Strata.RxNorm.Biz.Test.Unit.RxNorm { [TestFixture] public class TestRxNormBase { public VerifySettings VerifySetting { get; set; } public List RxnRelations { get; set; } public List RxnConcepts { get; set; } public List RxnAttributes { get; set; } /// /// /// /// TTY == "BN" public IQueryable BrandNames { get; set; } /// /// /// /// TTY == "DF" public IQueryable DoseForms { get; set; } /// /// /// /// TTY == "DFG" public IQueryable DoseFormGroups { get; set; } /// /// /// /// TTY == "SCD" public IQueryable GenericDrugs { get; set; } /// /// /// /// TTY == "SCD" public IQueryable SemanticBrandDrugs { get; set; } /// /// /// /// Atn == "NDC" public IQueryable Ndcs { get; set; } /// Generic Drugs /// where Tty == "SCD" protected IEnumerable rxngenericdrugs => RxnConcepts.Where(r => r.Tty == "SCD"); /// RxnConcept where Tty == "DF" protected IEnumerable rxndoseforms => RxnConcepts.Where(r => r.Tty == "DF"); /// RxnConcept where Tty == "DFG" protected IEnumerable rxndoseformgroups => RxnConcepts.Where(r => r.Tty == "DFG"); /// RxnConcept where Tty == "SCDC" protected IEnumerable rxncomponents => RxnConcepts.Where(r => r.Tty == "SCDC"); /// RxnConcept where Tty == "IN" protected IEnumerable rxningredients => RxnConcepts.Where(r => r.Tty == "IN"); /// Brand Name /// RxnConcept where Tty == "BN" protected IEnumerable rxnbrandnames => RxnConcepts.Where(r => r.Tty == "BN"); protected IEnumerable rxnstrengths => RxnAttributes.Where(s => s.Atn == "RXN_STRENGTH"); protected IEnumerable RxnComponents => from d in RxnConcepts.Where(r => r.Tty == "SCDC") join s in RxnAttributes.Where(s => s.Atn == "RXN_STRENGTH") on d.Rxcui equals s.Rxcui select new RxnComponent(d, s); protected IEnumerable RxnComponentIngredients => from r in RxnRelations join s in RxnAttributes.Where(s => s.Atn == "RXN_STRENGTH") on r.Rxcui1 equals s.Rxcui join d in RxnConcepts.Where(r => r.Tty == "SCDC") on r.Rxcui1 equals d.Rxcui into rd from rdx in rd.DefaultIfEmpty() join i in RxnConcepts.Where(r => r.Tty == "IN") on r.Rxcui2 equals i.Rxcui into ri from rix in ri.DefaultIfEmpty() select new RxnComponentIngredient { Key = int.TryParse(r.Rxcui1, out var cui) ? cui : 0, ComponentRxcui = r.Rxcui1, IngredientRxcui = r.Rxcui2, ComponentDescription = rdx?.Str ?? "--", IngredientDescription = rix?.Str ?? "--", Strength = s.Atv }; /// SemanticBrandedDrugs, Tty == "SCD" && Tty == "SCDC" protected IEnumerable RxnGenericComponents => from r in RxnRelations join g in RxnConcepts.Where(r => r.Tty == "SCD") on r.Rxcui1 equals g.Rxcui join c in RxnConcepts.Where(r => r.Tty == "SCDC") on r.Rxcui2 equals c.Rxcui select new RxnGenericComponent { Key = int.TryParse(r.Rxcui1, out var cui) ? cui : 0, GenericRxcui = r.Rxcui1, GenericDescription = g.Str, ComponentRxcui = r.Rxcui2, ComponentDescription = c.Str }; /// SemanticBrandedDrugs, Tty == "SBD" && Tty == "SCD" protected IEnumerable RxnSemanticBrandedDrugs => from r in RxnRelations join bd in RxnConcepts.Where(r => r.Tty == "SBD") on r.Rxcui1 equals bd.Rxcui join gd in RxnConcepts.Where(r => r.Tty == "SCD") on r.Rxcui2 equals gd.Rxcui orderby bd.Str select new FlattenConso(r, bd, gd, null, null); /// BrandedDrugs, Tty == "SBD" && Tty == "BN" protected IEnumerable BrandedDrugNames => from r in RxnRelations join bd in RxnConcepts.Where(r => r.Tty == "SBD") on r.Rxcui1 equals bd.Rxcui join bn in RxnConcepts.Where(r => r.Tty == "BN") on r.Rxcui2 equals bn.Rxcui orderby bn.Str select new FlattenConso(r, bn, bd, null, null); protected IEnumerable BrandedDrugGenericDrugNames => from r in RxnRelations join bd in BrandedDrugNames on r.Rxcui1 equals bd.RRxcui1 join gd in RxnConcepts.Where(r => r.Tty == "SCD") on r.Rxcui2 equals gd.Rxcui orderby bd.Str1 select new FlattenConso(r, bd.conso[0], bd.conso[1], gd, null); [OneTimeSetUp] public async Task SetUpFixture() { VerifySetting = TestExtensions.TestSettings(); RxnConcepts = "RXNCONSO.RRF".LoadRxnConcepts().ToList(); RxnRelations = "RXNREL1A.RRF".LoadRxnRelations() .Union("RXNREL1B.RRF".LoadRxnRelations()) .Union("RXNREL2A.RRF".LoadRxnRelations()) .Union("RXNREL2B.RRF".LoadRxnRelations()) .ToList(); RxnAttributes = "RXNSAT1A.RRF".LoadRxnAttributes() .Union("RXNSAT1B.RRF".LoadRxnAttributes()) .Union("RXNSAT2A.RRF".LoadRxnAttributes()) .Union("RXNSAT2B.RRF".LoadRxnAttributes()) .Union("RXNSAT3A.RRF".LoadRxnAttributes()) .Union("RXNSAT3B.RRF".LoadRxnAttributes()).ToList(); BrandNames = QueryRxnConcept("BN"); DoseFormGroups = QueryRxnConcept("DFG"); DoseForms = QueryRxnConcept("DF"); SemanticBrandDrugs = QueryRxnConcept("SCD"); Ndcs = QueryRxnAttribute("NDC"); } public IQueryable QueryRxnConcept(string tty) => (from c in RxnConcepts where c.Tty == tty orderby c.Str select new Rxndata(c)).AsQueryable(); public IQueryable QueryRxnAttribute(string atn) => (from c in RxnAttributes where c.Atn == atn orderby c.Atv select new Rxndata(c)).AsQueryable(); [TestCase("66490069110")] public async Task TestNdc(string ndc) { var Relations = (from a in Ndcs.Where(n => n.Description == ndc) //RxnAttributes.Where(ra => ra.Atn == "NDC" && ra.Atv == ndc) join r in RxnRelations on a.Rxcui equals r.Rxcui2 join b in RxnConcepts on r.Rxcui1 equals b.Rxcui select b); await Verifier.Verify(Relations, VerifySetting) .UseFileName(TestContext.CurrentContext.TestName()); } [TestCaseSource(nameof(RxnConceptsTestCases))] public async Task TestDimRxNormConcepts(int take, int skip, string tty) { IEnumerable concepts; switch (tty) { case "BN": concepts = RxnConcepts .Where(c => c.Tty == tty) .Select(x => new DimBrandName(x)) .OrderBy(x => x.Code).Skip(skip).Take(take); break; case "DF": concepts = RxnConcepts .Where(c => c.Tty == tty) .Select(x => new DimDoseForm(x)) .OrderBy(x => x.Code).Skip(skip).Take(take); break; case "SBD": concepts = RxnConcepts .Where(c => c.Tty == tty) .Select(x => new DimBrandedDrug(x)) .OrderBy(x => x.Code).Skip(skip).Take(take); break; case "SCD": concepts = RxnConcepts .Where(c => c.Tty == tty) .Select(x => new DimSemanticDrug(x)) .OrderBy(x => x.Code).Skip(skip).Take(take); break; default: return; } await Verifier.Verify(concepts, VerifySetting) .UseFileName(TestContext.CurrentContext.TestName()); } [TestCase(100, 0)] public async Task TestFactNdc(int take, int skip) { var attributes = RxnAttributes .Where(a => a.Atn == "NDC") .Select(a => new FactNdc { Ndc = a.Atv }) .OrderBy(a => a.Ndc) .Skip(skip).Take(take); await Verifier.Verify(attributes, VerifySetting) .UseFileName(TestContext.CurrentContext.TestName()); } [TestCase()] public async Task TestAdvil() { var dimBrandNames = RxnConcepts.Where(c => c.Tty == "BN").Select(x => new DimBrandName(x)); var brandNames = dimBrandNames.Where(c => c.Description.Contains("Advil", System.StringComparison.CurrentCultureIgnoreCase)); await Verifier.Verify(brandNames, VerifySetting) .UseFileName(TestContext.CurrentContext.TestName()); } [TestCase()] public async Task TestIbuprofen() { var dimBrandNames = RxnConcepts.Where(c => c.Tty == "IN").Select(x => new DimBrandName(x)); var brandNames = dimBrandNames.Where(c => c.Description.Contains("Ibuprofen", System.StringComparison.CurrentCultureIgnoreCase)); await Verifier.Verify(brandNames, VerifySetting) .UseFileName(TestContext.CurrentContext.TestName()); } [TestCase()] public async Task TestIbuprofenIngredients() { var ibuprofen = RxnConcepts .Where(c => c.Tty == "IN" && c.Str.Contains("Ibuprofen", System.StringComparison.CurrentCultureIgnoreCase)) .ToList(); var rxcuis = ibuprofen.Select(x => x.Rxcui); var brandNames = RxnConcepts.Where(c => c.Tty == "BN").ToList() .Join(RxnRelations.Where(r => rxcuis.Contains(r.Rxcui2)), b => b.Rxcui, r => r.Rxcui1, (b, r) => new { b, r }) .Join(ibuprofen, r => r.r.Rxcui2, c => c.Rxcui, (r, b) => new DimBrandName(r.b)) .OrderBy(b => b.Description); await Verifier.Verify(brandNames, VerifySetting) .UseFileName(TestContext.CurrentContext.TestName()); } [TestCase(100, 0)] public async Task TestBrandNames(int take, int skip) { var dimBrandNames = RxnConcepts.Where(c => c.Tty == "BN").Select(x => new DimBrandName(x)); var brandNames = BrandNames.Skip(skip).Take(take).ToList(); await Verifier.Verify(brandNames, VerifySetting) .UseFileName(TestContext.CurrentContext.TestName()); } [TestCaseSource(nameof(RxnConceptsTestCases))] public async Task TestRxcuiCode(int take, int skip, string tty) { if (take > 0) { var rxnConcepts = RxnConcepts .Where(c => (c.Tty == tty || string.IsNullOrEmpty(tty)) && c.Code != c.Rxcui) .Skip(skip).Take(take).ToList(); await Verifier.Verify(rxnConcepts, VerifySetting) .UseFileName(TestContext.CurrentContext.TestName()); return; } var concepts = RxnConcepts .Where(c => c.Code != c.Rxcui) .GroupBy(c => c.Tty, (TTY, concepts) => new ConceptGroup { Tty = TTY, Concepts = concepts.Select(c => new ConceptDump(c)) .OrderBy(c => c.Code) .ThenBy(c => c.Rxcui) }); await Verifier.Verify(concepts, VerifySetting) .UseFileName(TestContext.CurrentContext.TestName()); } internal class ConceptGroup { public string Tty { get; set; } public IEnumerable Concepts { get; set; } } internal class ConceptDump { public string Rxcui { get; set; } public string Code { get; set; } public ConceptDump(RxnConcept concept) { Rxcui = concept.Rxcui; Code = concept.Code; } } public static IEnumerable RxnConceptsTestCases() { yield return new TestCaseData(0, 0, "") .SetName("{m} Generic"); yield return new TestCaseData(100, 0, "BN") .SetName("{m} " + nameof(DimBrandName)); yield return new TestCaseData(100, 0, "DF") .SetName("{m} " + nameof(DimDoseForm)); yield return new TestCaseData(100, 0, "SBD") .SetName("{m} " + nameof(DimBrandedDrug)); yield return new TestCaseData(100, 0, "SCD") .SetName("{m} " + nameof(DimSemanticDrug)); } [TestCase(100, 0)] public async Task TestNdcs(int take, int skip) { var ndcs = Ndcs.Skip(skip).Take(take).ToList(); await Verifier.Verify(ndcs, VerifySetting) .UseFileName(TestContext.CurrentContext.TestName()); } [TestCase()] public async Task TestConceptTypes() { var conceptTypes = RxnConcepts .GroupBy(c => c.Tty, (Tty, d) => new { Tty, Count = d.Count() }) .OrderBy(c => c.Tty).ToList(); await Verifier.Verify(conceptTypes, VerifySetting) .UseFileName(TestContext.CurrentContext.TestName()); } [TestCase()] /// /// Populate the rxngenericdrugs table: /// - Extract Generic Drug Descriptions /// -- Identify all Semantic Clinical Drug Terms in the concepts table by looking for TTY(Term Type) SCD /// -- Extract these rows, interpreting Rxcui as GenericRxcui and Description as GenericDrugDescription /// - Extract Dose Forms /// -- Identify all Dose Form Terms in the concepts table by looking for TTY(Tevarrm Type) DF /// -- Extract these rows, interpreting Rxcui as DoseFormRxcui and Description as DoseFormDescription /// - Complete Generic Drugs table by adding dose form /// -- Limit CUI Relations table to rows where Rxcui1 has type SCD and Rxcui2 has type DF /// -- Extract these rows, intepreting Rxcui1 as GenericRxcui and Rxcui2 as DoseFormRxcui /// -- Join the above to Generic Drug Descriptions, keeping GenericRxcui, GenericDrugDescription, and DoseFormRxcui /// public async Task Populate_the_rxngenericdrugs_table() { var genericDrugDescriptions = rxngenericdrugs.Select(r => new Rxndata(r)).OrderBy(r => r.Description); var doseForms = rxndoseforms.Select(r => new Rxndata(r)).OrderBy(r => r.Description); var genericDrugs = from r in RxnRelations join gd in rxngenericdrugs on r.Rxcui1 equals gd.Rxcui join df in rxndoseforms on r.Rxcui2 equals df.Rxcui select new { GenericRxcui = gd.Rxcui, GernericDrugDescription = gd.Str, DoseFormRxcui = df.Rxcui, DoseForm = df.Str }; await Verifier.Verify(genericDrugDescriptions.ToList(), VerifySetting) .UseFileName(TestContext.CurrentContext.TestName(nameof(genericDrugDescriptions))); await Verifier.Verify(doseForms.ToList(), VerifySetting) .UseFileName(TestContext.CurrentContext.TestName(nameof(doseForms))); await Verifier.Verify(genericDrugs.ToList(), VerifySetting) .UseFileName(TestContext.CurrentContext.TestName(nameof(genericDrugs))); } [TestCase()] /// /// Populate Components and Ingredients /// - Populate Ingredients Table /// -- Identify all RxnConcepts with TTY(Term Type) IN /// -- Extract these rows, interpreting Rxcui as IngredientRxcui and Description as IngredientDescription /// - Populate Components Table /// -- Get Component Descriptions /// --- Identify all concepts with TTY(Term Type) SCDC(Semantic Clinical Drug Component) /// --- Extract these rows, interpreting Rxcui as ComponentRxcui and Description as ComponentDescription /// -- Get Component Strengths /// --- Identify all attribute rows the Rxcui has TTY SCDC and where Atn(Attribute Name) is RXN_STRENGTH /// --- Extract these rows, interpreting Rxcui as ComponentRxcui and Atv(Attribute Value) as Strength /// -- Get Component Ingredients /// --- Identify all rows in cui_Relations where Rxcui1 has TTY SCDC and Rxcui2 has TTY IN /// --- Extract these rows, interpreting Rxcui1 as ComponentRxcui and Rxcui2 as IngredientRxcui /// -- Complete Components Table /// --- Every ComponentRxcui should have one ComponentDescription, one Strength, and one IngredientRxcui. /// --- The table should have these four columns /// public async Task Populate_Components_and_Ingrediaents() { var ingredients = rxningredients.Select(r => new Rxndata(r)).OrderBy(r => r.Description); var componentDescriptions = rxncomponents.Select(r => new Rxndata(r)).OrderBy(r => r.Description); var strengths = rxnstrengths.Select(r => new Rxndata(r)).OrderBy(r => r.Description); var componentStrengths = from r in RxnRelations join c in rxncomponents on r.Rxcui1 equals c.Rxcui join s in rxnstrengths on r.Rxcui2 equals s.Rxcui select new RxnComponent(c, s); var componentIngredients = from r in RxnRelations join c in rxncomponents on r.Rxcui1 equals c.Rxcui join s in rxningredients on r.Rxcui2 equals s.Rxcui select new RxnComponent(c, s); var components = from c in componentDescriptions join s in componentStrengths on c.Key equals s.Key into cs from csx in cs.DefaultIfEmpty() join i in componentIngredients on c.Key equals i.Key into ci from cix in ci.DefaultIfEmpty() orderby (cix?.Rxcui2 == null ? 1 : 0), csx?.Attribute select new { c.Key, ComponentRxcui = c?.Rxcui, ComponentDescription = c?.Description, IngredientRxcui = cix?.Rxcui2, Strength = csx?.Attribute }; await Verifier.Verify(ingredients, VerifySetting) .UseFileName(TestContext.CurrentContext.TestName(nameof(ingredients))); await Verifier.Verify(componentDescriptions, VerifySetting) .UseFileName(TestContext.CurrentContext.TestName(nameof(componentDescriptions))); await Verifier.Verify(componentStrengths, VerifySetting) .UseFileName(TestContext.CurrentContext.TestName(nameof(componentStrengths))); await Verifier.Verify(componentIngredients, VerifySetting) .UseFileName(TestContext.CurrentContext.TestName(nameof(componentIngredients))); await Verifier.Verify(components, VerifySetting) .UseFileName(TestContext.CurrentContext.TestName(nameof(components))); } [TestCase()] /// /// Populate Generic Drug Components Table /// - Limit CUI Relations to rows where Rxcui1 has TTY SCD and Rxcui2 has TTY SCDC /// - Extract these rows, interpreting Rxcui1 as GenericRxcui and Rxcui2 as ComponentRxcui /// public async Task Populate_Generic_Drug_Components_Table() { var genericDrugDescriptions = rxngenericdrugs.Select(r => new Rxndata(r)).OrderBy(r => r.Description).ToList(); var doseForms = rxndoseforms.Select(r => new Rxndata(r)).OrderBy(r => r.Description).ToList(); var genericDrugs = from r in RxnRelations join gd in rxngenericdrugs on r.Rxcui1 equals gd.Rxcui join df in rxndoseforms on r.Rxcui2 equals df.Rxcui select new RxnComponent(gd, df); var ingredients = rxningredients.Select(r => new Rxndata(r)).OrderBy(r => r.Description).ToList(); var componentDescriptions = rxncomponents.Select(r => new Rxndata(r)).OrderBy(r => r.Description).ToList(); var strengths = rxnstrengths.Select(r => new Rxndata(r)).OrderBy(r => r.Description).ToList(); var componentStrengths = from s in rxnstrengths join c in rxncomponents on s.Rxcui equals c.Rxcui select new RxnComponent(c, s); var componentIngredients = from r in RxnRelations join c in rxncomponents on r.Rxcui1 equals c.Rxcui join i in rxningredients on r.Rxcui2 equals i.Rxcui select new RxnComponent(c, i); var components = from c in componentDescriptions join s in componentStrengths on c.Key equals s.Key into cs from csx in cs.DefaultIfEmpty() join i in componentIngredients on c.Key equals i.Key into ci from cix in ci.DefaultIfEmpty() select new { c, csx, cix }; var genericComponents = from r in RxnRelations join g in genericDrugs on r.Rxcui1 equals g.Rxcui join c in components on r.Rxcui2 equals c.c.Rxcui select new { ComponentRxcui = r.Rxcui2, GenericRxcui = r.Rxcui1 }; await Verifier.Verify(genericComponents, VerifySetting) .UseFileName(TestContext.CurrentContext.TestName()); } [TestCase()] /// /// Populate Branded Drug Tables /// - Populate Brand Names /// -- Limit concepts to terms with TTY(Term Type) BN(Brand Name) /// -- Extract these rows, interpreting Rxcui as BrandNameRxcui and Description as BrandName /// - Populate Branded Drugs /// -- Get Branded Drug Descriptions /// --- Limit concepts to terms with TTY(Term Type) SBD(Semantic Branded Drug) /// --- Extract these rows, interpreting Rxcui as BrandedDrugRxcui and Description as BrandedDrugDescription /// -- Get Branded Drug Generic Drugs /// --- Limit CUI Relations to rows where Rxcui1 has TTY SBD and Rxcui2 has TTY SCD /// --- Extract these rows, interpreting Rxcui1 as BrandedDrugRxcui and Rxcui2 as GenericRxcui /// -- Get Branded Drug Brand Names /// --- Limit CUI Relations to rows where Rxcui has TTY SBD and Rxcui2 as TTY BN /// --- Extract these rows, interpreting Rxcui1 as BrandedDrugRxcui and Rxcui2 as BrandNameRxcui /// -- Get Branded Drug Dose Forms /// --- Join Branded Drug Generic Drugs to Generic Drugs on GenericRxcui /// --- Get DoseFormRxcui for each BrandedDrugRxcui /// -- Combine Information to get columns /// --- BrandedDrugRxcui /// --- BrandedDrugDescription /// --- GenericRxcui /// --- GenericDrugDescription /// --- BrandNameRxcui /// --- DoseFormRxcui /// public async Task Populate_Branded_Drug_Tables() { var Bn = (from c in RxnConcepts where c.Tty == "BN" select new { BrandName = c.Str, BrandNameRxcui = c.Rxcui }); var Bdd = (from c in RxnConcepts where c.Tty == "SBD" select new { BrandedDrugName = c.Str, BrandedDrugRxcui = c.Rxcui }); var BdGd = (from r in RxnRelations join c1 in RxnConcepts.Where(c => c.Tty == "SBD") on r.Rxcui1 equals c1.Rxcui join c2 in RxnConcepts.Where(c => c.Tty == "SCD") on r.Rxcui2 equals c2.Rxcui select new { BrandedDrugRxcui = r.Rxcui1, BrandedDrugName = c1.Str, GenericRxcui = r.Rxcui2, GenericDrugName = c2.Str }); var Gdd = (from c in RxnConcepts where c.Tty == "SCD" select new { GenericDrugName = c.Str, GenericRxcui = c.Rxcui }); var Df = (from c in RxnConcepts where c.Tty == "DF" select new { DoseFormDescription = c.Str, DoseFormRxcui = c.Rxcui }); var Gd = (from r in RxnRelations join gd in Gdd on r.Rxcui1 equals gd.GenericRxcui join df in Df on r.Rxcui2 equals df.DoseFormRxcui select new { gd.GenericRxcui, gd.GenericDrugName, df.DoseFormRxcui, DoseForm = df.DoseFormDescription }); var BdBn = (from r in RxnRelations join c1 in RxnConcepts.Where(c => c.Tty == "SBD") on r.Rxcui1 equals c1.Rxcui join c2 in RxnConcepts.Where(c => c.Tty == "BN") on r.Rxcui2 equals c2.Rxcui select new { BrandedDrugRxcui = r.Rxcui1, BrandedDrugName = c1.Str, BrandNameRxcui = r.Rxcui2, BrandName = c2.Str }); var BrandedDrugDoseForms = ( from bdgd in BdGd join bn in BdBn on bdgd.BrandedDrugRxcui equals bn.BrandedDrugRxcui into bnj from bnji in bnj.DefaultIfEmpty() join g in Gd on bdgd.GenericRxcui equals g.GenericRxcui into gj from gji in gj.DefaultIfEmpty() join n in Ndcs on bdgd.BrandedDrugRxcui equals n.Rxcui into nj from nji in nj.DefaultIfEmpty() //where bnji == null orderby bnji?.BrandName, bdgd.BrandedDrugName, gji?.DoseForm select new { Ndc = nji?.Description, BrandName = bnji?.BrandName ?? "Generic", bdgd.BrandedDrugName, gji?.GenericDrugName, gji?.DoseForm, bnji?.BrandNameRxcui, bdgd.BrandedDrugRxcui, gji?.GenericRxcui, gji?.DoseFormRxcui, //Strength = s.Description }); await Verifier.Verify(BrandedDrugDoseForms, VerifySetting) .UseFileName(TestContext.CurrentContext.TestName()); } [TestCase(10, 0)] public async Task PublishFactRxNorm(int take, int skip) { var ndcDoseForms = from rel in RxnRelations join ndc in RxnAttributes.Where(a => a.Atn == "NDC") on rel.Rxcui1 equals ndc.Rxcui join df in RxnConcepts.Where(c => c.Tty == "DF") on rel.Rxcui2 equals df.Rxcui select new { NDC = ndc.Atv, NdcCode = ndc.Code, DoseForm = df.Str, DoseFormCode = df.Code, NdcRxcui = rel.Rxcui1, DoseFormRxcui = rel.Rxcui2, rel.Rel }; var SemanticClinicalDrugName = from r in RxnRelations join c1 in RxnConcepts.Where(c => c.Tty == "SCD") on r.Rxcui1 equals c1.Rxcui join c2 in RxnConcepts.Where(c => c.Tty == "SBD") on r.Rxcui2 equals c2.Rxcui select new { SemanticClinicalDrugRxcui = r.Rxcui1, SemanticClinicalDrugName = c1.Str, SemanticClinicalDrugCode = c1.Code, SemanticClinicalNameRxcui = r.Rxcui2, SemanticClinicalName = c2.Str, SemanticClinicalCode = c2.Code }; var SemanticBrandBrandName = from r in RxnRelations join c1 in RxnConcepts.Where(c => c.Tty == "SBD") on r.Rxcui1 equals c1.Rxcui join c2 in RxnConcepts.Where(c => c.Tty == "BN") on r.Rxcui2 equals c2.Rxcui select new { BrandedDrugRxcui = r.Rxcui1, BrandedDrugName = c1.Str, BrandedDrugCode = c1.Code, BrandNameRxcui = r.Rxcui2, BrandName = c2.Str, BrandCode = c2.Code }; var ndcDoseFormBrands = from rel in RxnRelations join ndc in ndcDoseForms on rel.Rxcui1 equals ndc.NdcRxcui join b in RxnConcepts.Where(c => c.Tty == "BN") on rel.Rxcui2 equals b.Rxcui into ndcb from ndcj in ndcb.DefaultIfEmpty() join sbd in SemanticBrandBrandName on rel.Rxcui2 equals sbd.BrandedDrugRxcui into sbds from sbdj in sbds.DefaultIfEmpty() select new { ndc.NDC, ndc.NdcCode, ndc.DoseForm, ndc.DoseFormCode, Brand = ndcj?.Str ?? "Not Specified", BrandCode = ndcj?.Code ?? "Not Specified", ndc.NdcRxcui, ndc.DoseFormRxcui, BrandRxcui = ndcj?.Rxcui ?? "", }; var ndcDFBSBD = from rel in RxnRelations join ndc in ndcDoseFormBrands on rel.Rxcui1 equals ndc.NdcRxcui join sbd in SemanticBrandBrandName on rel.Rxcui2 equals sbd.BrandedDrugRxcui into ndcs from ndcj in ndcs.DefaultIfEmpty() select new { ndc.NDC, ndc.NdcCode, ndc.DoseForm, ndc.DoseFormCode, ndc.Brand, ndc.BrandCode, SemanticBrand = ndcj?.BrandedDrugName ?? "Not Specified", SemanticBrandCode = ndcj?.BrandedDrugCode ?? "Not Specified", SemanticBrandName = ndcj?.BrandName ?? "Not Specified", SemanticBrandNameCode = ndcj?.BrandCode ?? "Not Specified", ndc.NdcRxcui, ndc.DoseFormRxcui, ndc.BrandRxcui, SemanticBrandRxcui = ndcj?.BrandedDrugRxcui ?? "", SemanticBrandNameRxcui = ndcj?.BrandNameRxcui ?? "", }; var ndcDFBSBDSCD = from rel in RxnRelations join ndc in ndcDFBSBD on rel.Rxcui1 equals ndc.NdcRxcui join sbd in SemanticClinicalDrugName on rel.Rxcui2 equals sbd.SemanticClinicalDrugRxcui select new { ndc.NDC, ndc.NdcCode, ndc.DoseForm, ndc.DoseFormCode, ndc.Brand, ndc.BrandCode, ndc.SemanticBrand, ndc.SemanticBrandCode, ndc.SemanticBrandName, ndc.SemanticBrandNameCode, SemanticClinicalBrand = sbd.SemanticClinicalDrugName, SemanticClinicalBrandCode = sbd.SemanticClinicalDrugCode, SemanticClinicalBrandName = sbd.SemanticClinicalName, SemanticClinicalBrandNameCode = sbd.SemanticClinicalCode, ndc.NdcRxcui, ndc.DoseFormRxcui, ndc.BrandRxcui, ndc.SemanticBrandRxcui, ndc.SemanticBrandNameRxcui, SemanticClinicalBrandRxcui = sbd.SemanticClinicalDrugRxcui, SemanticClinicalBrandNameRxcui = sbd.SemanticClinicalNameRxcui, }; await Verifier.Verify(ndcDFBSBDSCD .Where(b => b.Brand != "Not Specified" && b.SemanticBrand != "Not Specified") .OrderBy(b => b.NDC) .ThenBy(b => b.DoseFormCode) .ThenBy(b => b.BrandCode) .Distinct() .Skip(skip).Take(take), VerifySetting) .UseFileName(TestContext.CurrentContext?.TestName()); } internal class CheckForDuplicate { public string Code { get; set; } public IEnumerable Names { get; set; } public CheckForDuplicate(string code, IEnumerable names) { Code = code; Names = names; } } internal class DuplicateCheck { public IEnumerable Duplicates { get; set; } public int DuplicateCount { get; set; } public DuplicateCheck(IEnumerable items) { DuplicateCount = items.Count(x => x.Names.Count() > 1); Duplicates = items.Where(x => x.Names.Count() > 1); } } [TestCase()] public async Task CheckForDuplicateBrands() { var items = RxnConcepts.Where(b => b.Tty == "BN") .GroupBy(b => b.Code, (Code, d) => new CheckForDuplicate(Code, d.Select(n => n.Str))) .OrderBy(x => x.Code) .ToList(); var check = new DuplicateCheck(items); await Verifier.Verify(check, VerifySetting) .UseFileName(TestContext.CurrentContext?.TestName()); } [TestCase()] public async Task CheckForDuplicateDoseForms() { var items = RxnConcepts.Where(b => b.Tty == "DF") .GroupBy(b => b.Code, (Code, d) => new CheckForDuplicate(Code, d.Select(n => n.Str))) .OrderBy(x => x.Code) .ToList(); var check = new DuplicateCheck(items); await Verifier.Verify(check, VerifySetting) .UseFileName(TestContext.CurrentContext?.TestName()); } [TestCase()] public async Task CheckForDuplicateSemanticClinicalDrugs() { var items = RxnConcepts.Where(b => b.Tty == "SCD") .GroupBy(b => b.Code, (Code, d) => new CheckForDuplicate(Code, d.Select(n => n.Str))) .OrderBy(x => x.Code) .ToList(); var check = new DuplicateCheck(items); await Verifier.Verify(check, VerifySetting) .UseFileName(TestContext.CurrentContext?.TestName()); } [TestCase()] public async Task CheckForDuplicateSemanticBrandedDrugs() { var items = RxnConcepts.Where(b => b.Tty == "SBD") .GroupBy(b => b.Code, (Code, d) => new CheckForDuplicate(Code, d.Select(n => n.Str))) .OrderBy(x => x.Code) .ToList(); var check = new DuplicateCheck(items); await Verifier.Verify(check, VerifySetting) .UseFileName(TestContext.CurrentContext?.TestName()); } [TestCase(100, 0)] public async Task CheckForDuplicateNDCs(int take, int skip) { var items = RxnAttributes.Where(b => b.Atn == "NDC") .GroupBy(b => b.Code, (Code, d) => new CheckForDuplicate(Code, d.Select(n => n.Atv))) .OrderBy(x => x.Code) .Skip(skip).Take(take) .ToList(); var check = new DuplicateCheck(items); await Verifier.Verify(check, VerifySetting) .UseFileName(TestContext.CurrentContext?.TestName()); } } }