Mosquito Collections from Start to Finish
So your agency wants to record surveillance and testing information in VectorSurv using the VectorSurv API. What would this process look like?
Let's look at an example: A user at a local control agency, Davis Public Health Department, out of Davis, California, trapped mosquitoes at a new location in Central Park, and sent pools of those mosquitoes to a lab for arbovirus testing.
We can get these surveillance records into VectorSurv with a series of four API requests:
- Create a site
- Create a collection at that site
- Create mosquito pools associated with that collection
- Create pool results for that pool
Creating the site
Sites provide context for surveillance activity. A new site should be created for any location that will see more than one instance of surveillance activity. View the documentation for creating a new site.
Site details
The new site is located behind the carousel in Central Park, which itself is located at the intersection of 5th Street and B Street in Davis, California. In accordance with DPHD conventions, the new "Central Park Carousel" is assigned site code "000123".
Using this information and the documentation, an API user can construct an object that describes the new site. An annotated version of that object might look like this:
const site = {
active_date: "2023-05-05", // Date from which surveillance activity occurs in this location
address_1: "5th Street & B Street", // Street address
city: "Davis",
region: 6, // Region ID corresponding to California
postal_code: "95616", //
code: "000123", // 6 digit site code
comments: "Collection site behind the carousel in Central Park",
coordinate_precision: 2, // ID corresponding to level of precision to which coordinates are known.
name: "Central Park Carousel",
shape: {
type: "Point",
coordinates: [-127.45, 38.546], // Longitude and latitude of the new site
},
site_population: "Suburban", // "Suburban", "Urban", or "Rural"
site_land_usage: [5], // Land usage ID corresponding to "Park/Cemetery/Golf Course"
};
Making the Request
That same object could be used to define the request body in a POST
request to create the site:
curl -X POST 'https://api.vectorsurv.org/v1/site' \
-H "Authorization: Bearer DPHD_user_auth_token" \
-H "Content-Type: application/json" \
-d '{
"active_date": "2023-05-05",
"address_1": "5th Street & B Street",
"city": "Davis",
"region": 6,
"postal_code": "95616",
"code": "000123",
"comments": "Collection site behind the carousel in Central Park",
"coordinate_precision": 2,
"name": "Central Park Carousel",
"shape": {
"type": "Point",
"coordinates": [-127.45, 38.546]
},
"site_population": "Suburban",
"site_land_usage": [5]
}'
Interpreting the Response
On success, the response body details the site record that was created, including the id
, which will be useful for associating collections with this location.
{
"active_date": "2023-05-05T00:00:00.000Z",
"code": "000123",
"name": "Central Park Carousel",
"coordinate_precision": 2,
"shape": {
"crs": {
"type": "name",
"properties": {
"name": "EPSG:4326"
}
},
"type": "Point",
"coordinates": [-127.45, 38.546]
},
"region": 6,
"postal_code": "95616",
"city": "Davis",
"site_land_usage": [5],
"address_1": "5th Street & 26 B Street",
"agency": 123,
"deactive_date": null,
"elevation": null,
"user": 456,
"id": 90002,
"add_date": "2023-06-01T00:00:00.000Z",
"address_2": null,
"comments": "Collection site behind the carousel in Central Park",
"revision_comments": null,
"updated": "2023-06-01T00:00:00.000Z"
}
Creating a collection at the new site
Surveillance activity can be associated with one or more sites to provide more context for the surveillance activity. View the documentation for creating a new collection.
Collection Details
The first collection at the new site happened on May 06, 2023. A CO2 Trap with a dry ice lure ran for one night with no problems, catching 13 female Cx. tarsalis and 7 female Cs. incidens. In accordance with DPHD conventions, the collection is assigned collection number 42.
Using this information and the documentation, an API user can construct an object that describes the new collection. An annotated version of that object might look like this:
const collection = {
collection_date: "2023-05-06",
collection_num: 42,
comments: "First collection at new site",
identified_by: "Hector Collector",
num_trap: 1,
site: 90002, // ID corresponding to site where the collection occurred
trap: 2, // ID corresponding to CO2 trap
trap_nights: 1, // Ran for 1 night
trap_problem_bit: false, // No issues
arthropods: [
{
species: 70, // tarsalis
sex: 4, // ID corresponding to female
num_count: 13,
},
{
species: 57, // incidens
sex: 4, // ID corresponding to female
num_count: 7,
},
],
lures: [32], // ID corresponding to dry ice lure
};
Making the Request
That same object could be used to define the request body in a POST
request to create the collection:
curl -X POST 'https://api.vectorsurv.org/v1/arthropod/collection' \
-H "Authorization: Bearer DPHD_user_auth_token" \
-H "Content-Type: application/json" \
-d '{
"collection_date": "2023-05-06",
"collection_num": 42,
"comments": "First collection at new site",
"identified_by": "Hector Collector",
"num_trap": 1,
"site": 90002,
"trap": 2,
"trap_nights": 1,
"trap_problem_bit": false,
"arthropods": [
{
"species": 70,
"sex": 4,
"num_count": 13
},
{
"species": 57,
"sex": 4,
"num_count": 7
}
],
"lures": [32]
}'
Interpreting the Response
On success, the response body details the collection record that was created, including the id
, which will be useful for creating pools with this collection.
{
"add_date": "2023-06-01T00:00:00.000Z",
"updated": "2023-06-01T00:00:00.000Z",
"id": 66001,
"collection_date": "2023-05-06T00:00:00.000Z",
"collection_num": 42,
"comments": "First collection at new site",
"identified_by": "Hector",
"num_trap": 1,
"site": 90002,
"trap": 2,
"trap_nights": 1,
"trap_problem_bit": false,
"agency": 123,
"collection_date_date_only": true,
"surv_year": 2023,
"user": 456,
"deactive_date": null,
"location": {
"table_name": "arthro_collection",
"record_id": 66001,
"agency": 123,
"shape": {
"crs": {
"type": "name",
"properties": {
"name": "EPSG:4326"
}
},
"type": "Point",
"coordinates": [-127.45, 38.546]
},
"coordinate_precision": 2
},
"arthropods": [
{
"id": 30013,
"species": 70,
"sex": 4,
"num_count": 13,
"collection": 66001,
"agency": 123,
"deactive_date": null
},
{
"id": 30012,
"species": 57,
"sex": 4,
"num_count": 7,
"collection": 66001,
"agency": 123,
"deactive_date": null
}
],
"lures": [
{
"add_date": "2023-06-07T18:02:50.658Z",
"id": 30039,
"table_name": "arthro_collection",
"record_id": 66001,
"agency": 123,
"lure": 32,
"deactive_date": null
}
]
}
Creating pools associated with that collection
Pool records can be associated with existing collections to provide more context to the pool. View the documentation for creating a new mosquito pool.
Pool Details
DPHD then created a pool of 5 female Cx. tarsalis out of that collection, which they plan to send to their testing lab. In accordance with DPHD conventions, the new pool is assigned pool number 123001.
Using this information and the documentation, an API user can construct an object that describes the new pool. An annotated version of that object might look like this:
const pool = {
collection: 66001, // ID corresponding to the collection from which the pool is drawn
comments: "Culex pool from collection 123",
num_count: 5,
pool_num: 123001,
primary_source_bit: true, // Indicating that the pool's contents are primarily drawn from the associated collection
species: 70,
sex: 4,
};
Making the Request
That same object could be used to define the request body in a POST
request to create the collection:
curl -X POST 'https://api.vectorsurv.org/v1/arthropod/pool' \
--header 'Authorization: Bearer DPHD_user_auth_token' \
--header 'Content-Type: application/json' \
-d '{
"collection": 66001,
"comments": "Culex pool from collection 123",
"num_count": 5,
"pool_num": 123001,
"primary_source_bit": true,
"species": 70,
"sex": 4
}'
Interpreting the Response
On success, the response body details the pool record that was created, including the id
, which will be useful for associating test results with this pool.
{
"collection": 66001,
"comments": "Culex pool from collection 123",
"num_count": 5,
"pool_num": 222,
"primary_source_bit": true,
"species": 70,
"sex": 4,
"agency": 123,
"site": null,
"surv_year": 2023,
"user": 11,
"location": {
"shape": {
"crs": {
"type": "name",
"properties": {
"name": "EPSG:4326"
}
},
"type": "Point",
"coordinates": [-116, 36]
},
"coordinate_precision": 2
},
"id": 66602,
"primary_source": 66602,
"add_date": "2023-06-07T19:07:18.145Z"
}
Adding test records for those pools
Finally, DPHD received negative test results back from the lab. View the documentation for creating a new test record.
Test Record Data
Pool 123001 was RTPCR tested for WNV by a third party lab on May 08, 2023. The results were a conclusive "Negative".
Using this information and the documentation, an API user can construct an object that describes the pool test. An annotated version of that object might look like this:
const testResult = {
pool: 66602, // ID corresponding to the Pool 123001, created in the last step
method: 5, // ID corresponding to RTPCR testing
target: 6, // ID corresponding to WNV
status: 1, // ID corresponding to 'Negative'
test_date: "2023-05-08",
user: 11, // ID corresponding to the API user
test_agency: 123, // Because the lab is outside the VectorSurv network, ID corresponding to DCPH is used
};
Making the Request
That same object could be used to define the request body in a POST
request to create the test record:
library(httr)
library(jsonlite)
createTestResult <- function(token) {
headers = c(
Authorization = paste("Bearer", token),
"Content-Type" = "application/json"
)
url <- "https://api.vectorsurv.org/v1/arthropod/pool/test"
body <- list(
pool = 66602,
method = 5,
target = 6,
status = 1,
test_date = "2023-05-08",
user = 11,
test_agency = 123
)
tryCatch({
# Make the API request
response <- POST(url, body = jsonlite::toJSON(body, auto_unbox = TRUE), add_headers(headers))
# Check the response status code and category
status_code <- http_status(response)$status_code
status_category <- http_status(response)$category
if (status_category == "Success") {
# Response status is successful (e.g., status code 200)
content <- httr::content(response, "text")
# Use response data frame if needed
content_df = fromJSON(content)
message("Post request was successful")
} else {
# Response status is not successful (e.g., status code 422)
response_content <- httr::content(response, 'text')
message("Error response content:", response_content)
}
}, error = function(e) {
# Any other exceptions that might occur during the API request
message("An error occurred during the API request. Error message:", e$message)
})
}
createTestResult("DPHD_user_auth_token")
Interpreting the Response
As this is the last step in the process, DPHD would have little use for the response body. For completeness, it is included anyway: