Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
- checks species match using name matching server
  • Loading branch information
temi committed May 17, 2024
1 parent 1ac3b7e commit f803982
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 42 deletions.
1 change: 1 addition & 0 deletions grails-app/conf/application.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,7 @@ if (!ala.baseURL) {
}
bie.ws.url = "https://bie-ws.ala.org.au/"
bie.url = "https://bie.ala.org.au/"
namesmatching.url = "https://namematching-ws-test.ala.org.au/"

if (!collectory.baseURL) {
//collectory.baseURL = "https://collectory-dev.ala.org.au/"
Expand Down
33 changes: 20 additions & 13 deletions grails-app/services/au/org/ala/ecodata/ParatooService.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ class ParatooService {
RecordService recordService
MetadataService metadataService
UserService userService
SpeciesReMatchService speciesReMatchService

/**
* The rules we use to find projects eligible for use by paratoo are:
Expand Down Expand Up @@ -2053,7 +2054,7 @@ class ParatooService {
/**
* Transforms a species name to species object used by ecodata.
* e.g. Acacia glauca [Species] (scientific: Acacia glauca Willd.)
* [name: "Acacia glauca Willd.", scientificName: "Acacia glauca Willd.", guid: "A_GUID"]
* [name: "Acacia glauca Willd.", scientificName: "Acacia glauca Willd.", commonName: "Acacia glauca", guid: "A_GUID"]
* Guid is necessary to generate species occurrence record. Guid is found by searching the species name with BIE. If not found, then a default value is added.
* @param name
* @return
Expand All @@ -2064,28 +2065,34 @@ class ParatooService {
}

String regex = "([^\\[\\(]*)(?:\\[(.*)\\])?\\s*(?:\\(scientific:\\s*(.*?)\\))?"
String commonName, scientificName = name
Pattern pattern = Pattern.compile(regex)
Matcher matcher = pattern.matcher(name)
Map result = [name: name, scientificName: name, commonName: name, outputSpeciesId: UUID.randomUUID().toString()]
Map result = [scientificName: name, commonName: name, outputSpeciesId: UUID.randomUUID().toString()]

if (matcher.find()) {
String commonName = matcher.group(1)?.trim()
String scientificName = matcher.group(3)?.trim()
result.commonName = commonName ?: result.commonName
commonName = matcher.group(1)?.trim()
scientificName = matcher.group(3)?.trim()
result.taxonRank = matcher.group(2)?.trim()
result.scientificName = scientificName ?: commonName ?: result.scientificName
result.name = scientificName ?: commonName ?: result.name
result.scientificName = scientificName
result.commonName = commonName
}

metadataService.autoPopulateSpeciesData(result)
Map resp = speciesReMatchService.searchByName(scientificName)
if (resp) {
result.putAll(resp)
}
// try again with common name
if ((result.guid == null) && result.commonName) {
def speciesObject = [scientificName: result.commonName]
metadataService.autoPopulateSpeciesData(speciesObject)
result.guid = speciesObject.guid
result.scientificName = result.scientificName ?: speciesObject.scientificName
if ((result.guid == null) && commonName) {
resp = speciesReMatchService.searchByName(commonName)
if (resp) {
result.putAll(resp)
result.commonName = commonName
}
}

result.name = result.commonName ? result.scientificName ? "${result.scientificName} (${result.commonName})" : result.commonName : result.scientificName

// record is only created if guid is present
result.guid = result.guid ?: Record.UNMATCHED_GUID
result
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,36 @@ class SpeciesReMatchService {
webService.getJson(url)
})
}

Map searchByName (String name, boolean addDetails = false) {
Map result = searchNameMatchingServer(name)
if (result) {
Map resp = [
scientificName: result.scientificName,
commonName: result.vernacularName,
guid: result.taxonConceptID,
taxonRank: result.rank
]

if(addDetails) {
resp.put('details', result)
}

return resp
}
}

Map searchNameMatchingServer(String name) {
name = name?.toLowerCase() ?: ""
cacheService.get('name-matching-server-' + name, {
def encodedQuery = URLEncoder.encode(name ?: '', "UTF-8")
def url = "${grailsApplication.config.getProperty('namesmatching.url')}api/search?q=${encodedQuery}"
def resp = webService.getJson(url)
if (!resp.success) {
return null
}

resp
})
}
}
73 changes: 44 additions & 29 deletions src/test/groovy/au/org/ala/ecodata/ParatooServiceSpec.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class ParatooServiceSpec extends MongoSpec implements ServiceUnitTest<ParatooSer
TokenService tokenService = Mock(TokenService)
SettingService settingService = Mock(SettingService)
MetadataService metadataService = Mock(MetadataService)
SpeciesReMatchService speciesReMatchService = Mock(SpeciesReMatchService)
ActivityService activityService = Mock(ActivityService)
RecordService recordService = Mock(RecordService)
UserService userService = Mock(UserService)
Expand Down Expand Up @@ -55,6 +56,7 @@ class ParatooServiceSpec extends MongoSpec implements ServiceUnitTest<ParatooSer
service.recordService = recordService
service.cacheService = new CacheService()
service.userService = userService
service.speciesReMatchService = speciesReMatchService

JSON.registerObjectMarshaller(new MapMarshaller())
JSON.registerObjectMarshaller(new CollectionMarshaller())
Expand Down Expand Up @@ -654,25 +656,6 @@ class ParatooServiceSpec extends MongoSpec implements ServiceUnitTest<ParatooSer
result == ""
}

void "transformSpeciesName should convert paratoo species name to object correctly"() {
when:
Map result = service.transformSpeciesName("Acacia glauca [Species] (scientific: Acacia glauca Willd.)")
String outputSpeciesId = result.remove("outputSpeciesId")
then:
outputSpeciesId != null
result == [name: "Acacia glauca Willd.", scientificName: "Acacia glauca Willd.", guid: "A_GUID", commonName: "Acacia glauca", taxonRank: "Species"]
2 * metadataService.autoPopulateSpeciesData(_) >> null

when: // no scientific name
result = service.transformSpeciesName("Frogs [Class] (scientific: )")
outputSpeciesId = result.remove("outputSpeciesId")

then:
outputSpeciesId != null
result == [name: "Frogs", scientificName: "Frogs", guid: "A_GUID", commonName: "Frogs", taxonRank: "Class"]
2 * metadataService.autoPopulateSpeciesData(_) >> null
}

void "buildRelationshipTree should build relationship tree correctly"() {
given:
def properties = [
Expand Down Expand Up @@ -723,6 +706,25 @@ class ParatooServiceSpec extends MongoSpec implements ServiceUnitTest<ParatooSer
relationships["fauna-survey"].contains("fauna-observation")
}

void "transformSpeciesName should convert paratoo species name to object correctly"() {
when:
Map result = service.transformSpeciesName("Acacia glauca [Species] (scientific: Acacia glauca Willd.)")
String outputSpeciesId = result.remove("outputSpeciesId")
then:
outputSpeciesId != null
result == [name: "Acacia glauca Willd. (Acacia glauca)", scientificName: "Acacia glauca Willd.", guid: "A_GUID", commonName: "Acacia glauca", taxonRank: "Species"]
2 * speciesReMatchService.searchByName(_) >> null

when: // no scientific name
result = service.transformSpeciesName("Frogs [Class] (scientific: )")
outputSpeciesId = result.remove("outputSpeciesId")

then:
outputSpeciesId != null
result == [name: "Frogs", scientificName: "", guid: "A_GUID", commonName: "Frogs", taxonRank: "Class"]
2 * speciesReMatchService.searchByName(_) >> null
}

void "buildTreeFromParentChildRelationships should build tree correctly"() {
given:
def relationships = [
Expand Down Expand Up @@ -1399,13 +1401,19 @@ class ParatooServiceSpec extends MongoSpec implements ServiceUnitTest<ParatooSer
result.lut.remove('outputSpeciesId')

then:
1 * speciesReMatchService.searchByName(_) >> [
commonName: "Cat",
scientificName: "Felis catus",
guid: "TAXON_ID",
taxonRank: "species"
]
result == [
lut: [
commonName: "Cat",
name: "Cat",
taxonRank: null,
scientificName: "Cat",
guid: "A_GUID"
name: "Felis catus (Cat)",
taxonRank: "species",
scientificName: "Felis catus",
guid: "TAXON_ID"
]
]

Expand All @@ -1417,18 +1425,25 @@ class ParatooServiceSpec extends MongoSpec implements ServiceUnitTest<ParatooSer
]
]
output = [
lut: "Cat"
lut: "Cats [Species] (scientific: Felis catus)"
]
result = service.recursivelyTransformData(dataModel, output, formName, 1, null)
result.lut.remove('outputSpeciesId')
then:
1 * speciesReMatchService.searchByName("Felis catus") >> null
1 * speciesReMatchService.searchByName("Cats") >> [
commonName: "Cat",
scientificName: "Felis catus",
guid: "TAXON_ID",
taxonRank: "species"
]
result == [
lut: [
commonName: "Cat",
name: "Cat",
taxonRank: null,
scientificName: "Cat",
guid: "A_GUID"
commonName: "Cats",
name: "Felis catus (Cats)",
taxonRank: "species",
scientificName: "Felis catus",
guid: "TAXON_ID"
]
]
}
Expand Down

0 comments on commit f803982

Please sign in to comment.