public async Task RecognizeHealthcareEntitiesTest() { TextAnalyticsClient client = GetClient(); AnalyzeHealthcareEntitiesOperation operation = await client.StartAnalyzeHealthcareEntitiesAsync(s_batchDocuments); await operation.WaitForCompletionAsync(PollingInterval); 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); AnalyzeHealthcareEntitiesResult result1 = resultCollection[0]; Assert.AreEqual(s_document1ExpectedEntitiesOutput.Count, result1.Entities.Count); Assert.IsNotNull(result1.Id); Assert.AreEqual("1", result1.Id); foreach (HealthcareEntity entity in result1.Entities) { Assert.IsTrue(s_document1ExpectedEntitiesOutput.Contains(entity.Text)); if (entity.Text == "ibuprofen") { var linksList = new List <string> { "UMLS", "AOD", "ATC", "CCPSS", "CHV", "CSP", "DRUGBANK", "GS", "LCH_NW", "LNC", "MEDCIN", "MMSL", "MSH", "MTHSPL", "NCI", "NCI_CTRP", "NCI_DCP", "NCI_DTP", "NCI_FDA", "NCI_NCI-GLOSS", "NDDF", "PDQ", "RCD", "RXNORM", "SNM", "SNMI", "SNOMEDCT_US", "USP", "USPMG", "VANDF" }; foreach (EntityDataSource entityDataSource in entity.DataSources) { Assert.IsTrue(linksList.Contains(entityDataSource.Name)); } } // TODO - Implement HC preview.4 https://github.com/Azure/azure-sdk-for-net/issues/18984 //if (entity.Text == "100mg") //{ // Assert.IsTrue(entity.RelatedEntities.Count == 1); // var relatedEntity = entity.RelatedEntities.FirstOrDefault().Key; // Assert.AreEqual("ibuprofen", relatedEntity.Text); // Assert.AreEqual("MedicationName", relatedEntity.Category); // Assert.AreEqual(9, relatedEntity.Length); // Assert.AreEqual(27, relatedEntity.Offset); // Assert.AreEqual(1.0, relatedEntity.ConfidenceScore); // Assert.AreEqual(HealthcareEntityRelationType.DosageOfMedication, entity.RelatedEntities.FirstOrDefault().Value); //} } }
public async Task RecognizeHealthcareEntitiesTest() { TextAnalyticsClient client = GetClient(); AnalyzeHealthcareEntitiesOperation operation = await client.StartAnalyzeHealthcareEntitiesAsync(batchDocuments); await operation.WaitForCompletionAsync(PollingInterval); AnalyzeHealthcareEntitiesResultCollection resultCollection = operation.Value; Assert.AreEqual(2, resultCollection.Count); AnalyzeHealthcareEntitiesResult result = resultCollection[0]; var entitiesList = new List <string> { "100mg", "ibuprofen", "twice daily" }; Assert.AreEqual(3, result.Entities.Count); Assert.IsNotNull(result.Id); Assert.AreEqual("1", result.Id); foreach (HealthcareEntity entity in result.Entities) { Assert.IsTrue(entitiesList.Contains(entity.Text)); if (entity.Text == "ibuprofen") { var linksList = new List <string> { "UMLS", "AOD", "ATC", "CCPSS", "CHV", "CSP", "DRUGBANK", "GS", "LCH_NW", "LNC", "MEDCIN", "MMSL", "MSH", "MTHSPL", "NCI", "NCI_CTRP", "NCI_DCP", "NCI_DTP", "NCI_FDA", "NCI_NCI-GLOSS", "NDDF", "PDQ", "RCD", "RXNORM", "SNM", "SNMI", "SNOMEDCT_US", "USP", "USPMG", "VANDF" }; foreach (EntityDataSource entityDataSource in entity.DataSources) { Assert.IsTrue(linksList.Contains(entityDataSource.Name)); } } if (entity.Text == "100mg") { Assert.IsTrue(entity.RelatedEntities.Count == 1); var relatedEntity = entity.RelatedEntities.FirstOrDefault().Key; Assert.AreEqual("ibuprofen", relatedEntity.Text); Assert.AreEqual("MedicationName", relatedEntity.Category); Assert.AreEqual(0, relatedEntity.Length); Assert.AreEqual(27, relatedEntity.Offset); Assert.AreEqual(1.0, relatedEntity.ConfidenceScore); // TODO - DosageOfMedication is not in relation types and is returned from the service. Need to add to swagger. //Assert.AreEqual(HealthcareEntityRelationType.DosageOfMedication, entity.RelatedEntities.ElementAt(0).Value); } } }
public async Task RecognizeHealthcareEntitiesTest() { TextAnalyticsClient client = GetClient(); AnalyzeHealthcareEntitiesOperation operation = await client.StartAnalyzeHealthcareEntitiesAsync(s_batchDocuments); 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); AnalyzeHealthcareEntitiesResult result1 = resultCollection[0]; Assert.AreEqual(s_document1ExpectedEntitiesOutput.Count, result1.Entities.Count); Assert.IsNotNull(result1.Id); Assert.AreEqual("1", result1.Id); foreach (HealthcareEntity entity in result1.Entities) { Assert.IsTrue(s_document1ExpectedEntitiesOutput.Contains(entity.Text)); if (entity.Text == "ibuprofen") { var linksList = new List <string> { "UMLS", "AOD", "ATC", "CCPSS", "CHV", "CSP", "DRUGBANK", "GS", "LCH_NW", "LNC", "MEDCIN", "MMSL", "MSH", "MTHSPL", "NCI", "NCI_CTRP", "NCI_DCP", "NCI_DTP", "NCI_FDA", "NCI_NCI-GLOSS", "NDDF", "PDQ", "RCD", "RXNORM", "SNM", "SNMI", "SNOMEDCT_US", "USP", "USPMG", "VANDF" }; foreach (EntityDataSource entityDataSource in entity.DataSources) { Assert.IsTrue(linksList.Contains(entityDataSource.Name)); } } if (entity.Text == "100mg") { Assert.AreEqual(18, entity.Offset); Assert.AreEqual("Dosage", entity.Category); Assert.AreEqual(5, entity.Length); } } Assert.AreEqual(2, result1.EntityRelations.Count()); foreach (HealthcareEntityRelation relation in result1.EntityRelations) { if (relation.RelationType == "DosageOfMedication") { var role = relation.Roles.ElementAt(0); Assert.IsNotNull(relation.Roles); Assert.AreEqual(2, relation.Roles.Count()); Assert.AreEqual("Dosage", role.Name); Assert.AreEqual("100mg", role.Entity.Text); Assert.AreEqual(18, role.Entity.Offset); Assert.AreEqual("Dosage", role.Entity.Category); Assert.AreEqual(5, role.Entity.Length); } } }
public async Task RecognizeHealthcareEntitiesTestWithAssertions() { TextAnalyticsClient client = GetClient(); IReadOnlyCollection <string> batchDocuments = new List <string>() { "Baby not likely to have Meningitis. in case of fever in the mother, consider Penicillin for the baby too." }; IReadOnlyCollection <string> expectedEntitiesOutput = new List <string> { "Baby", "Meningitis", "fever", "mother", "Penicillin", "baby" }; AnalyzeHealthcareEntitiesOperation operation = await client.StartAnalyzeHealthcareEntitiesAsync(batchDocuments); await operation.WaitForCompletionAsync(); ValidateOperationProperties(operation); List <AnalyzeHealthcareEntitiesResultCollection> resultInPages = operation.Value.ToEnumerableAsync().Result; Assert.AreEqual(1, resultInPages.Count); var resultCollection = resultInPages.FirstOrDefault(); Assert.AreEqual(batchDocuments.Count, resultCollection.Count); AnalyzeHealthcareEntitiesResult result1 = resultCollection[0]; Assert.AreEqual(expectedEntitiesOutput.Count, result1.Entities.Count); foreach (HealthcareEntity entity in result1.Entities) { Assert.IsTrue(expectedEntitiesOutput.Contains(entity.Text)); if (entity.Text == "Baby") { var linksList = new List <string> { "UMLS", "AOD", "CCPSS", "CHV", "DXP", "LCH", "LCH_NW", "LNC", "MDR", "MSH", "NCI", "NCI_FDA", "NCI_NICHD", "SNOMEDCT_US" }; foreach (EntityDataSource entityDataSource in entity.DataSources) { Assert.IsTrue(linksList.Contains(entityDataSource.Name)); } Assert.AreEqual("Infant", entity.NormalizedText); } if (entity.Text == "Meningitis") { Assert.AreEqual(24, entity.Offset); Assert.AreEqual("Diagnosis", entity.Category); Assert.AreEqual(10, entity.Length); Assert.IsNotNull(entity.Assertion); Assert.AreEqual(EntityCertainty.NegativePossible, entity.Assertion.Certainty.Value); } if (entity.Text == "Penicillin") { Assert.AreEqual("MedicationName", entity.Category); Assert.AreEqual(10, entity.Length); Assert.IsNotNull(entity.Assertion); Assert.AreEqual(EntityCertainty.NeutralPossible, entity.Assertion.Certainty.Value); } } }
public static async Task RunAsync([EventGridTrigger] EventGridEvent eventGridEvent, ILogger log) { //Extracting content type and url of the blob triggering the function var jsondata = JsonConvert.SerializeObject(eventGridEvent.Data); var tmp = new { contentType = "", url = "" }; var data = JsonConvert.DeserializeAnonymousType(jsondata, tmp); //Checking if the trigger was iniatiated for a WAV File. if (data.contentType == "audio/wav") { var audioUrl = data.url; string blobName = audioUrl.Split('/').Last(); string contosoStorageConnectionString = System.Environment.GetEnvironmentVariable("ContosoStorageConnectionString", EnvironmentVariableTarget.Process); string speechRegion = System.Environment.GetEnvironmentVariable("SpeechRegion", EnvironmentVariableTarget.Process); string speechKey = System.Environment.GetEnvironmentVariable("SpeechKey", EnvironmentVariableTarget.Process); string translatorKey = System.Environment.GetEnvironmentVariable("TranslatorKey", EnvironmentVariableTarget.Process); string translatorEndpoint = System.Environment.GetEnvironmentVariable("TranslatorEndpoint", EnvironmentVariableTarget.Process); string translatorLocation = System.Environment.GetEnvironmentVariable("TranslatorLocation", EnvironmentVariableTarget.Process); string cosmosEndpointUrl = System.Environment.GetEnvironmentVariable("CosmosDBEndpointUrl", EnvironmentVariableTarget.Process); string cosmosPrimaryKey = System.Environment.GetEnvironmentVariable("CosmosDBPrimaryKey", EnvironmentVariableTarget.Process); string textAnalyticsKey = System.Environment.GetEnvironmentVariable("TextAnalyticsKey", EnvironmentVariableTarget.Process); string textAnalyticsEndpoint = System.Environment.GetEnvironmentVariable("TextAnalyticsEndpoint", EnvironmentVariableTarget.Process); // Download audio file to a local temp directory var tempPath = System.IO.Path.GetTempFileName(); BlobContainerClient container = new BlobContainerClient(contosoStorageConnectionString, "audiorecordings"); BlobClient blob = container.GetBlobClient(blobName); await blob.DownloadToAsync(tempPath); var speechConfig = SpeechConfig.FromSubscription(speechKey, speechRegion); speechConfig.SetProperty(PropertyId.SpeechServiceConnection_SingleLanguageIdPriority, "Latency"); // Audio Language Identification // Considering only two languages: English and Spanish // Languages supported for language detection : https://docs.microsoft.com/azure/cognitive-services/speech-service/language-support var autoDetectSourceLanguageConfig = AutoDetectSourceLanguageConfig.FromLanguages(new string[] { "en-US", "es-MX" }); string languageDetected = "en-US"; using (var audioInput = AudioConfig.FromWavFileInput(tempPath)) { using (var recognizer = new SourceLanguageRecognizer(speechConfig, autoDetectSourceLanguageConfig, audioInput)) { var result = await recognizer.RecognizeOnceAsync().ConfigureAwait(false); if (result.Reason == ResultReason.RecognizedSpeech) { var lidResult = AutoDetectSourceLanguageResult.FromResult(result); languageDetected = lidResult.Language; } } } speechConfig.SpeechRecognitionLanguage = languageDetected; // Audio Transcription StringBuilder sb = new StringBuilder(); using var audioConfig = AudioConfig.FromWavFileInput(tempPath); { using var recognizer = new SpeechRecognizer(speechConfig, audioConfig); { var stopRecognition = new TaskCompletionSource <int>(); recognizer.SessionStopped += (s, e) => { stopRecognition.TrySetResult(0); }; recognizer.Canceled += (s, e) => { stopRecognition.TrySetResult(0); }; recognizer.Recognized += (s, e) => { if (e.Result.Reason == ResultReason.RecognizedSpeech) { sb.Append(e.Result.Text); } else if (e.Result.Reason == ResultReason.NoMatch) { log.LogInformation($"NOMATCH: Speech could not be recognized."); } }; await recognizer.StartContinuousRecognitionAsync(); Task.WaitAny(new[] { stopRecognition.Task }); } } string transcribedText = sb.ToString(); // If transcription is in Spanish we will translate it to English if (!languageDetected.Contains("en")) { string route = $"/translate?api-version=3.0&to=en"; string textToTranslate = sb.ToString(); object[] body = new object[] { new { Text = textToTranslate } }; var requestBody = JsonConvert.SerializeObject(body); using (var client = new HttpClient()) using (var request = new HttpRequestMessage()) { request.Method = HttpMethod.Post; request.RequestUri = new Uri(translatorEndpoint + route); request.Content = new StringContent(requestBody, Encoding.UTF8, "application/json"); request.Headers.Add("Ocp-Apim-Subscription-Key", translatorKey); request.Headers.Add("Ocp-Apim-Subscription-Region", translatorLocation); HttpResponseMessage response = await client.SendAsync(request).ConfigureAwait(false); var responseBody = await response.Content.ReadAsStringAsync(); List <Model.TranslatorService.Root> translatedDocuments = JsonConvert.DeserializeObject <List <Model.TranslatorService.Root> >(responseBody); transcribedText = translatedDocuments.FirstOrDefault().Translations.FirstOrDefault().Text; } } //Azure Text Analytics for Healthcare List <string> healthDocuments = new List <string> { transcribedText }; var textAnalyticsClient = new TextAnalyticsClient(new Uri(textAnalyticsEndpoint), new AzureKeyCredential(textAnalyticsKey)); AnalyzeHealthcareEntitiesOperation healthOperation = textAnalyticsClient.StartAnalyzeHealthcareEntities(healthDocuments, "en", new AnalyzeHealthcareEntitiesOptions { }); await healthOperation.WaitForCompletionAsync(); AnalyzeHealthcareEntitiesResult healthcareResult = healthOperation.GetValues().FirstOrDefault().FirstOrDefault(); //Insert documents into CosmosDB var cosmosClient = new CosmosClient(cosmosEndpointUrl, cosmosPrimaryKey); var cosmosDatabase = (await cosmosClient.CreateDatabaseIfNotExistsAsync("Contoso")).Database; var cosmosContainer = (await cosmosDatabase.CreateContainerIfNotExistsAsync("Transcriptions", "/id")).Container; Model.Transcription newTranscription = new Model.Transcription(); newTranscription.Id = Guid.NewGuid().ToString(); newTranscription.DocumentDate = new DateTime(int.Parse(blobName.Substring(0, 4)), int.Parse(blobName.Substring(4, 2)), int.Parse(blobName.Substring(6, 2))); newTranscription.FileName = blobName; newTranscription.TranscribedText = transcribedText; foreach (var item in healthcareResult.Entities) { newTranscription.HealthcareEntities.Add(new Model.HealthcareEntity() { Category = item.Category, Text = item.Text }); } try { ItemResponse <Model.Transcription> cosmosResponse = await cosmosContainer.CreateItemAsync(newTranscription, new PartitionKey(newTranscription.Id)); } catch (CosmosException ex) when(ex.StatusCode == System.Net.HttpStatusCode.Conflict) { //Conflicting documents are silently ignored for demo purposes. } System.IO.File.Delete(tempPath); log.LogInformation(eventGridEvent.Data.ToString()); } }