Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TA] Implementation to support FHIR #28809

Merged
merged 5 commits into from
May 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions sdk/textanalytics/Azure.AI.TextAnalytics/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
## 5.2.0-beta.3 (Unreleased)

### Features Added
- Added keyword argument `FhirVersion` to `AnalyzeHealthcareEntitiesOptions`. Use the keyword to indicate the version for the property `AnalyzeHealthcareEntitiesResult.FhirBundle` that represents a FHIR compatible object for consumption in other Healthcare tools.
- Added property `FhirBundle` to `AnalyzeHealthcareEntitiesResult`.

### Breaking Changes
- Enum `EntityCategory.IPAddress` now uses the underlying string `IPAddress` value instead of `IP` to align with the Text Analytics service behavior.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,14 @@ public AnalyzeHealthcareEntitiesOperation(string operationId, Azure.AI.TextAnaly
public partial class AnalyzeHealthcareEntitiesOptions : Azure.AI.TextAnalytics.TextAnalyticsRequestOptions
{
public AnalyzeHealthcareEntitiesOptions() { }
public Azure.AI.TextAnalytics.Models.FhirVersion? FhirVersion { get { throw null; } set { } }
}
public partial class AnalyzeHealthcareEntitiesResult : Azure.AI.TextAnalytics.TextAnalyticsResult
{
internal AnalyzeHealthcareEntitiesResult() { }
public System.Collections.Generic.IReadOnlyCollection<Azure.AI.TextAnalytics.HealthcareEntity> Entities { get { throw null; } }
public System.Collections.Generic.IReadOnlyCollection<Azure.AI.TextAnalytics.HealthcareEntityRelation> EntityRelations { get { throw null; } }
public System.Collections.Generic.IReadOnlyDictionary<string, object> FhirBundle { get { throw null; } }
public System.Collections.Generic.IReadOnlyCollection<Azure.AI.TextAnalytics.TextAnalyticsWarning> Warnings { get { throw null; } }
}
public partial class AnalyzeHealthcareEntitiesResultCollection : System.Collections.ObjectModel.ReadOnlyCollection<Azure.AI.TextAnalytics.AnalyzeHealthcareEntitiesResult>
Expand Down Expand Up @@ -1036,7 +1038,9 @@ public static partial class TextAnalyticsModelFactory
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
public static Azure.AI.TextAnalytics.AnalyzeActionsResult AnalyzeActionsResult(System.Collections.Generic.IEnumerable<Azure.AI.TextAnalytics.ExtractKeyPhrasesActionResult> extractKeyPhrasesActionResult, System.Collections.Generic.IEnumerable<Azure.AI.TextAnalytics.RecognizeEntitiesActionResult> recognizeEntitiesActionResults, System.Collections.Generic.IEnumerable<Azure.AI.TextAnalytics.RecognizePiiEntitiesActionResult> recognizePiiEntitiesActionResults, System.Collections.Generic.IEnumerable<Azure.AI.TextAnalytics.RecognizeLinkedEntitiesActionResult> recognizeLinkedEntitiesActionsResults, System.Collections.Generic.IEnumerable<Azure.AI.TextAnalytics.AnalyzeSentimentActionResult> analyzeSentimentActionsResults) { throw null; }
public static Azure.AI.TextAnalytics.AnalyzeActionsResult AnalyzeActionsResult(System.Collections.Generic.IEnumerable<Azure.AI.TextAnalytics.ExtractKeyPhrasesActionResult> extractKeyPhrasesActionResults, System.Collections.Generic.IEnumerable<Azure.AI.TextAnalytics.RecognizeEntitiesActionResult> recognizeEntitiesActionResults, System.Collections.Generic.IEnumerable<Azure.AI.TextAnalytics.RecognizePiiEntitiesActionResult> recognizePiiEntitiesActionResults, System.Collections.Generic.IEnumerable<Azure.AI.TextAnalytics.RecognizeLinkedEntitiesActionResult> recognizeLinkedEntitiesActionResults, System.Collections.Generic.IEnumerable<Azure.AI.TextAnalytics.AnalyzeSentimentActionResult> analyzeSentimentActionResults, System.Collections.Generic.IEnumerable<Azure.AI.TextAnalytics.ExtractSummaryActionResult> extractSummaryActionResults, System.Collections.Generic.IEnumerable<Azure.AI.TextAnalytics.RecognizeCustomEntitiesActionResult> recognizeCustomEntitiesActionResults, System.Collections.Generic.IEnumerable<Azure.AI.TextAnalytics.SingleCategoryClassifyActionResult> singleCategoryClassifyActionResults, System.Collections.Generic.IEnumerable<Azure.AI.TextAnalytics.MultiCategoryClassifyActionResult> multiCategoryClassifyActionResults) { throw null; }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
public static Azure.AI.TextAnalytics.AnalyzeHealthcareEntitiesResult AnalyzeHealthcareEntitiesResult(string id, Azure.AI.TextAnalytics.TextDocumentStatistics statistics, System.Collections.Generic.IEnumerable<Azure.AI.TextAnalytics.HealthcareEntity> healthcareEntities, System.Collections.Generic.IEnumerable<Azure.AI.TextAnalytics.HealthcareEntityRelation> entityRelations, System.Collections.Generic.IEnumerable<Azure.AI.TextAnalytics.TextAnalyticsWarning> warnings) { throw null; }
public static Azure.AI.TextAnalytics.AnalyzeHealthcareEntitiesResult AnalyzeHealthcareEntitiesResult(string id, Azure.AI.TextAnalytics.TextDocumentStatistics statistics, System.Collections.Generic.IEnumerable<Azure.AI.TextAnalytics.HealthcareEntity> healthcareEntities, System.Collections.Generic.IEnumerable<Azure.AI.TextAnalytics.HealthcareEntityRelation> entityRelations, System.Collections.Generic.IEnumerable<Azure.AI.TextAnalytics.TextAnalyticsWarning> warnings, System.Collections.Generic.IDictionary<string, object> fhirBundle) { throw null; }
public static Azure.AI.TextAnalytics.AnalyzeHealthcareEntitiesResult AnalyzeHealthcareEntitiesResult(string id, string code, string message) { throw null; }
public static Azure.AI.TextAnalytics.AnalyzeHealthcareEntitiesResultCollection AnalyzeHealthcareEntitiesResultCollection(System.Collections.Generic.IEnumerable<Azure.AI.TextAnalytics.AnalyzeHealthcareEntitiesResult> list, Azure.AI.TextAnalytics.TextDocumentBatchStatistics statistics, string modelVersion) { throw null; }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using Azure.AI.TextAnalytics.Models;

namespace Azure.AI.TextAnalytics
{
/// <summary>
Expand All @@ -16,5 +18,14 @@ public class AnalyzeHealthcareEntitiesOptions : TextAnalyticsRequestOptions
public AnalyzeHealthcareEntitiesOptions()
{
}

/// <summary>
/// The FHIR Spec version that the result will use to format the <see cref="AnalyzeHealthcareEntitiesResult.FhirBundle"/>
/// on the result object. For additional information see <see href="https://www.hl7.org/fhir/overview.html"/> .
/// </summary>
/// <remarks>
/// This property only applies for <see cref="TextAnalyticsClientOptions.ServiceVersion.V2022_04_01_Preview"/> and up.
/// </remarks>
public FhirVersion? FhirVersion { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,19 @@ public partial class AnalyzeHealthcareEntitiesResult : TextAnalyticsResult
/// <summary>
/// Initializes a new instance of the <see cref="AnalyzeHealthcareEntitiesResult"/>.
/// </summary>
/// <param name="id">Analyze operation id.</param>
/// <param name="statistics">Info about text document statistics. <see cref="TextDocumentStatistics"/>.</param>
/// <param name="healthcareEntities">Extracted health care entities.</param>
/// <param name="entityRelations">Relations between the entities. <see cref="HealthcareEntityRelation"/>.</param>
/// <param name="warnings">Returned warnings from the operation.</param>
internal AnalyzeHealthcareEntitiesResult(string id, TextDocumentStatistics statistics,
IList<HealthcareEntity> healthcareEntities,
IList<HealthcareEntityRelation> entityRelations,
IList<TextAnalyticsWarning> warnings,
IDictionary<string, object> fhirBundle)
: this(id, statistics, healthcareEntities, entityRelations, warnings)
{
FhirBundle = new ReadOnlyDictionary<string, object>(fhirBundle);
}

/// <summary>
/// Initializes a new instance of the <see cref="AnalyzeHealthcareEntitiesResult"/>.
/// </summary>
internal AnalyzeHealthcareEntitiesResult(string id, TextDocumentStatistics statistics,
IList<HealthcareEntity> healthcareEntities,
IList<HealthcareEntityRelation> entityRelations,
Expand All @@ -32,6 +40,7 @@ internal AnalyzeHealthcareEntitiesResult(string id, TextDocumentStatistics stati
_entities = new ReadOnlyCollection<HealthcareEntity>(healthcareEntities);
Warnings = new ReadOnlyCollection<TextAnalyticsWarning>(warnings);
EntityRelations = new ReadOnlyCollection<HealthcareEntityRelation>(entityRelations);
FhirBundle = new Dictionary<string, object>();
}

/// <summary>
Expand Down Expand Up @@ -67,5 +76,15 @@ public IReadOnlyCollection<HealthcareEntity> Entities
/// Gets the relations between the entities. <see cref="HealthcareEntityRelation"/>.
/// </summary>
public IReadOnlyCollection<HealthcareEntityRelation> EntityRelations { get; }

/// <summary>
/// If <see cref="AnalyzeHealthcareEntitiesOptions.FhirVersion"/> is set, this will contain a
/// FHIR compatible object for consumption in other Healthcare tools.
/// For additional information see <see href="https://www.hl7.org/fhir/overview.html"/> .
/// </summary>
/// <remarks>
/// This property only applies for <see cref="TextAnalyticsClientOptions.ServiceVersion.V2022_04_01_Preview"/> and up.
/// </remarks>
public IReadOnlyDictionary<string, object> FhirBundle { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1286,7 +1286,8 @@ private static HealthcareLROTask CreateHealthcareTask(AnalyzeHealthcareEntitiesO
{
ModelVersion = options.ModelVersion,
StringIndexType = Constants.DefaultStringIndexType,
LoggingOptOut = options.DisableServiceLogs
LoggingOptOut = options.DisableServiceLogs,
maririos marked this conversation as resolved.
Show resolved Hide resolved
FhirVersion = options.FhirVersion ?? (FhirVersion?)null
}
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1390,6 +1390,7 @@ public static RecognizePiiEntitiesActionResult RecognizePiiEntitiesActionResult(
/// <param name="entityRelations">Sets the collection of <see cref="TextAnalytics.HealthcareEntityRelation"/>.</param>
/// <param name="warnings">Sets the collection of <see cref="TextAnalytics.TextAnalyticsWarning"/>.</param>
/// <returns>A new instance of <see cref="TextAnalytics.AnalyzeHealthcareEntitiesResult"/> for mocking purposes.</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public static AnalyzeHealthcareEntitiesResult AnalyzeHealthcareEntitiesResult(
string id,
TextDocumentStatistics statistics,
Expand All @@ -1400,6 +1401,27 @@ public static AnalyzeHealthcareEntitiesResult AnalyzeHealthcareEntitiesResult(
return new AnalyzeHealthcareEntitiesResult(id, statistics, healthcareEntities.ToList(), entityRelations.ToList(), warnings.ToList());
}

/// <summary>
/// Initializes a new instance of <see cref="TextAnalytics.AnalyzeHealthcareEntitiesResult"/> for mocking purposes.
/// </summary>
/// <param name="id">Sets the <see cref="TextAnalyticsResult.Id"/> property.</param>
/// <param name="statistics">Sets the <see cref="TextAnalyticsResult.Statistics"/> property.</param>
/// <param name="healthcareEntities">Sets the collection of <see cref="TextAnalytics.HealthcareEntity"/>.</param>
/// <param name="entityRelations">Sets the collection of <see cref="TextAnalytics.HealthcareEntityRelation"/>.</param>
/// <param name="warnings">Sets the collection of <see cref="TextAnalytics.TextAnalyticsWarning"/>.</param>
/// <param name="fhirBundle">Sets the object <see cref="AnalyzeHealthcareEntitiesResult.FhirBundle"/>.</param>
/// <returns>A new instance of <see cref="TextAnalytics.AnalyzeHealthcareEntitiesResult"/> for mocking purposes.</returns>
public static AnalyzeHealthcareEntitiesResult AnalyzeHealthcareEntitiesResult(
string id,
TextDocumentStatistics statistics,
IEnumerable<HealthcareEntity> healthcareEntities,
IEnumerable<HealthcareEntityRelation> entityRelations,
IEnumerable<TextAnalyticsWarning> warnings,
IDictionary<string, object> fhirBundle)
{
return new AnalyzeHealthcareEntitiesResult(id, statistics, healthcareEntities.ToList(), entityRelations.ToList(), warnings.ToList(), fhirBundle);
}

/// <summary>
/// Initializes a new instance of <see cref="TextAnalytics.AnalyzeHealthcareEntitiesResult"/> for mocking purposes.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,8 @@ internal static AnalyzeHealthcareEntitiesResultCollection ConvertToAnalyzeHealth
documentHealthcareEntities.Statistics ?? default,
ConvertToHealthcareEntityCollection(documentHealthcareEntities.Entities),
ConvertToHealthcareEntityRelationsCollection(documentHealthcareEntities.Entities, documentHealthcareEntities.Relations),
ConvertToWarnings(documentHealthcareEntities.Warnings)));
ConvertToWarnings(documentHealthcareEntities.Warnings),
documentHealthcareEntities.FhirBundle));
}

healthcareEntititesResults = healthcareEntititesResults.OrderBy(result => idToIndexMap[result.Id]).ToList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Azure.AI.TextAnalytics.Models;
using Azure.Core.TestFramework;
using NUnit.Framework;

Expand Down Expand Up @@ -443,6 +444,35 @@ public async Task AnalyzeHealthcareEntitiesPagination()
Assert.AreEqual(2, pages[0].Count);
}

[RecordedTest]
[ServiceVersion(Min = TextAnalyticsClientOptions.ServiceVersion.V2022_04_01_Preview)]
maririos marked this conversation as resolved.
Show resolved Hide resolved
public async Task RecognizeHealthcareEntitiesWithFhir()
{
TextAnalyticsClient client = GetClient(useTokenCredential: true);

AnalyzeHealthcareEntitiesOptions options = new AnalyzeHealthcareEntitiesOptions()
{
FhirVersion = FhirVersion.Four01
maririos marked this conversation as resolved.
Show resolved Hide resolved
};

AnalyzeHealthcareEntitiesOperation operation = await client.StartAnalyzeHealthcareEntitiesAsync(s_batchDocuments, options);

await operation.WaitForCompletionAsync();

ValidateOperationProperties(operation);

List<AnalyzeHealthcareEntitiesResultCollection> resultInPages = operation.Value.ToEnumerableAsync().Result;
Assert.AreEqual(1, resultInPages.Count);

//Take the first page
var resultCollection = resultInPages.FirstOrDefault();
Assert.AreEqual(s_batchDocuments.Count, resultCollection.Count);

//Check Fhirbundle has content on it
Assert.IsNotNull(resultCollection[0].FhirBundle);
Assert.Greater(resultCollection[0].FhirBundle.Count, 0);
}

private void ValidateInDocumenResult(IReadOnlyCollection<HealthcareEntity> entities, List<string> minimumExpectedOutput)
{
Assert.GreaterOrEqual(entities.Count, minimumExpectedOutput.Count);
Expand Down Expand Up @@ -497,6 +527,8 @@ private void ValidateBatchDocumentsResult(AnalyzeHealthcareEntitiesResultCollect
}

Assert.IsNotNull(entitiesInDocument.Warnings);
Assert.IsNotNull(entitiesInDocument.EntityRelations);
Assert.IsNotNull(entitiesInDocument.FhirBundle);
maririos marked this conversation as resolved.
Show resolved Hide resolved
ValidateInDocumenResult(entitiesInDocument.Entities, minimumExpectedOutput[entitiesInDocument.Id]);
}
}
Expand Down
Loading