Created
July 7, 2025 19:32
-
-
Save geoffdougherty1/2c02aa03e19f2657127668d8e31dc8be to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function agent_step!(patient::Patient, model) | |
| # run some sanity checks on agent values | |
| @argcheck patient.nurseComplete == false || patient.nurseElapsedTime > 0 | |
| if patient.status > 2 && "TR" in patient.path | |
| # @argcheck patient.careComplete == true | |
| end | |
| # only patients with missing ESI are direct admits | |
| if patient.esi ==-1 | |
| @argcheck "Direct-IP" in patient.path | |
| end | |
| # control patient flow based on status. | |
| # 1 = waiting room, 2 = ED treatment, 3 = IP, 4 = discharged | |
| if patient.status == 4 && (abmtime(model) - patient.dischargeTime) > 30 | |
| # this can be executed for performance reasons, | |
| # or commented out to keep track of all agents over time | |
| #remove_agent!(patient, model) | |
| # work backward from end of pipeline. First, discharge inpatients | |
| elseif patient.status == 3 && (abmtime(model) - patient.admitTime) > patient.personalIpLos #discharge IP at end of stay | |
| patient.status = 4 | |
| patient.dischargeTime = abmtime(model) | |
| move_agent!(patient, (rand(31:60), rand(1:30)), model::ABM) | |
| model.dischargedIp += 1 | |
| push!(patient.path,"DISCH-IP") | |
| elseif patient.status == 2 #process patients being treated in ED | |
| if patient.ipRequired == 1 && patient.careComplete == true | |
| @argcheck 1 <= patient.ipUnit <=length(model.ipCapacityNow) | |
| if count(x -> x.status == 3 && x.ipUnit == patient.ipUnit, allagents(model)) < model.ipCapacityNow[patient.ipUnit] | |
| patient.status = 3 | |
| patient.admitTime = abmtime(model) | |
| move_agent!(patient, (rand(31:60), rand(31:60)), model::ABM) | |
| patient.ed1 = round(Int, (abmtime(model) - (patient.arrivalTime))) | |
| model.admittedIp += 1 | |
| push!(patient.path, "IP") | |
| else | |
| patient.boardingTime += 1 | |
| # provide MD/RN care for patients who are boarding | |
| if mod(patient.boardingTime,120) == 0 | |
| patient.docVisitsReq += 1 | |
| patient.docReqTotalTime + 5 | |
| patient.docComplete = false | |
| end | |
| if mod(patient.boardingTime,60) == 0 | |
| patient.nurseVisitsReq += 1 | |
| patient.nurseReqTotalTime + 5 | |
| patient.nurseComplete = false | |
| end | |
| end | |
| # discharge patient going home from ED | |
| elseif patient.ipRequired == 0 && patient.careComplete == true | |
| patient.status = 4 | |
| patient.dischargeTime = abmtime(model) | |
| move_agent!(patient, (rand(31:60), rand(1:30)), model::ABM) | |
| patient.op18 = round(Int, (abmtime(model) - (patient.arrivalTime))) | |
| model.dischargedOp += 1 | |
| push!(patient.path,"DISCH-OP") | |
| @argcheck patient.dischargeTime>patient.arrivalTime | |
| @argcheck patient.docVisitCount >= patient.docVisitsReq | |
| #for those remaining in treatment space, see if they need first nurse/doc visit | |
| elseif patient.nurseVisitCount == 0 | |
| nurseVisit(patient, model) | |
| @argcheck patient.dxComplete == false | |
| elseif patient.docVisitCount == 0 | |
| doctorVisit(patient, model) | |
| # if not currently needing first visit from providers, do diagnostics | |
| elseif patient.dxComplete == false | |
| processTests(patient, model) | |
| # execute remaining provider visit | |
| elseif patient.docComplete == false | |
| doctorVisit(patient, model) | |
| elseif patient.nurseComplete == false | |
| nurseVisit(patient, model) | |
| @argcheck patient.careComplete == false | |
| elseif patient.transported == false | |
| transport(patient, model) | |
| # if no services required, mark as care complete. | |
| # This cues patient for discharge home or move to IP | |
| elseif patient.dxComplete && patient.nurseComplete == true && patient.docComplete == true && patient.transported == true | |
| patient.careComplete = true | |
| patient.careCompleteTime = abmtime(model) | |
| @argcheck patient.docElapsedTime>0 | |
| else | |
| error("shouldn't be here ") | |
| end | |
| elseif patient.status == 1 ## process people in waiting room | |
| if count(x -> x.status == 2, allagents(model)) < model.edCapacity | |
| patient.status = 2 | |
| patient.treatmentTime = abmtime(model) | |
| x = rand(1:30) | |
| y = rand(31:60) | |
| move_agent!(patient, (x, y), model::ABM) | |
| push!(patient.path,"TR") | |
| # elseif model.lbws[patient.esi] < rand() | |
| # left without being seen | |
| # patient.status = 4 | |
| # patient.dischargeTime = abmtime(model) ?? does op18 include lwbs | |
| # move_agent!(patient, (rand(31:60), rand(1:30)), model::ABM) | |
| #model.dischargedIp += 1 | |
| end | |
| end | |
| end | |
| # agents.jl requires a step function for each agent subtype. Doc/nurse behavior | |
| # is governed by their interaction w/ patients in the patient step. Adding docs/nurses | |
| # according to staffing requirements is done in model step. So nothing to do here. | |
| function agent_step!(doctor::Doctor, model) | |
| nothing | |
| end | |
| function agent_step!(nurse::Nurse, model) | |
| nothing | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment