825 lines
37 KiB
C#
825 lines
37 KiB
C#
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<RxnRelation> RxnRelations { get; set; }
|
|
public List<RxnConcept> RxnConcepts { get; set; }
|
|
public List<RxnAttribute> RxnAttributes { get; set; }
|
|
|
|
/// <summary>
|
|
/// <seealso cref="RxnConcept"/>
|
|
/// </summary>
|
|
/// <remarks>TTY == "BN"</remarks>
|
|
public IQueryable<Rxndata> BrandNames { get; set; }
|
|
/// <summary>
|
|
/// <seealso cref="RxnConcept"/>
|
|
/// </summary>
|
|
/// <remarks>TTY == "DF"</remarks>
|
|
public IQueryable<Rxndata> DoseForms { get; set; }
|
|
/// <summary>
|
|
/// <seealso cref="RxnConcept"/>
|
|
/// </summary>
|
|
/// <remarks>TTY == "DFG"</remarks>
|
|
public IQueryable<Rxndata> DoseFormGroups { get; set; }
|
|
/// <summary>
|
|
/// <seealso cref="RxnConcept"/>
|
|
/// </summary>
|
|
/// <remarks>TTY == "SCD"</remarks>
|
|
public IQueryable<Rxndata> GenericDrugs { get; set; }
|
|
/// <summary>
|
|
/// <seealso cref="RxnConcept"/>
|
|
/// </summary>
|
|
/// <remarks>TTY == "SCD"</remarks>
|
|
public IQueryable<Rxndata> SemanticBrandDrugs { get; set; }
|
|
/// <summary>
|
|
/// <seealso cref="RxnAttribute"/>
|
|
/// </summary>
|
|
/// <remarks>Atn == "NDC"</remarks>
|
|
public IQueryable<Rxndata> Ndcs { get; set; }
|
|
|
|
/// <summary>Generic Drugs</summary>
|
|
/// <remarks><see cref="RxnConcept"/> where Tty == "SCD"</remarks>
|
|
protected IEnumerable<RxnConcept> rxngenericdrugs => RxnConcepts.Where(r => r.Tty == "SCD");
|
|
/// <summary>RxnConcept where Tty == "DF"</summary>
|
|
protected IEnumerable<RxnConcept> rxndoseforms => RxnConcepts.Where(r => r.Tty == "DF");
|
|
/// <summary>RxnConcept where Tty == "DFG"</summary>
|
|
protected IEnumerable<RxnConcept> rxndoseformgroups => RxnConcepts.Where(r => r.Tty == "DFG");
|
|
/// <summary>RxnConcept where Tty == "SCDC"</summary>
|
|
protected IEnumerable<RxnConcept> rxncomponents => RxnConcepts.Where(r => r.Tty == "SCDC");
|
|
/// <summary>RxnConcept where Tty == "IN"</summary>
|
|
protected IEnumerable<RxnConcept> rxningredients => RxnConcepts.Where(r => r.Tty == "IN");
|
|
/// <summary>Brand Name</summary>
|
|
/// <remarks>RxnConcept where Tty == "BN"</remarks>
|
|
protected IEnumerable<RxnConcept> rxnbrandnames => RxnConcepts.Where(r => r.Tty == "BN");
|
|
|
|
protected IEnumerable<RxnAttribute> rxnstrengths => RxnAttributes.Where(s => s.Atn == "RXN_STRENGTH");
|
|
|
|
protected IEnumerable<RxnComponent> 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<RxnComponentIngredient> 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
|
|
};
|
|
|
|
/// <summary>SemanticBrandedDrugs, Tty == "SCD" && Tty == "SCDC"</summary>
|
|
protected IEnumerable<RxnGenericComponent> 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
|
|
};
|
|
|
|
/// <summary>SemanticBrandedDrugs, Tty == "SBD" && Tty == "SCD"</summary>
|
|
protected IEnumerable<FlattenConso> 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);
|
|
|
|
/// <summary>BrandedDrugs, Tty == "SBD" && Tty == "BN"</summary>
|
|
protected IEnumerable<FlattenConso> 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<FlattenConso> 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<Rxndata> QueryRxnConcept(string tty)
|
|
=> (from c in RxnConcepts
|
|
where c.Tty == tty
|
|
orderby c.Str
|
|
select new Rxndata(c)).AsQueryable();
|
|
|
|
public IQueryable<Rxndata> 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<IRxNormConcept> 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<ConceptDump> 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<TestCaseData> 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()]
|
|
/// <summary>
|
|
/// 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
|
|
/// </summary>
|
|
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()]
|
|
/// <summary>
|
|
/// Populate Components and Ingredients
|
|
/// - Populate Ingredients Table
|
|
/// -- Identify all <c>RxnConcept</c>s 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
|
|
/// </summary>
|
|
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()]
|
|
/// <summary>
|
|
/// 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
|
|
/// </summary>
|
|
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()]
|
|
/// <summary>
|
|
/// 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
|
|
/// </summary>
|
|
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<string> Names { get; set; }
|
|
|
|
public CheckForDuplicate(string code, IEnumerable<string> names)
|
|
{
|
|
Code = code;
|
|
Names = names;
|
|
}
|
|
}
|
|
|
|
internal class DuplicateCheck
|
|
{
|
|
public IEnumerable<CheckForDuplicate> Duplicates { get; set; }
|
|
public int DuplicateCount { get; set; }
|
|
|
|
public DuplicateCheck(IEnumerable<CheckForDuplicate> 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());
|
|
}
|
|
}
|
|
|
|
}
|