Skip to content

Instantly share code, notes, and snippets.

@prerakmody
Last active July 13, 2023 09:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save prerakmody/2b97434dcb2727599bc852a9b8758651 to your computer and use it in GitHub Desktop.
Save prerakmody/2b97434dcb2727599bc852a9b8758651 to your computer and use it in GitHub Desktop.
Raystation - Dual Arc Beam
import connect
RS_CHECK_PREFIX = '_'
RS_STR_TRANSLATE_OBJ = { ord(' ') : ord('_') , ord('(') : ord('_') , ord(')') : ord('_') , ord('-') : ord('_') , ord('+') : ord('_') , ord('<') : ord('_') , ord('>') : ord('_') }
KEYNAME_PATIENT = 'Patient'
def checkForRTPlan(case, planName):
exists = False
if RS_CHECK_PREFIX + str(planName).translate(RS_STR_TRANSLATE_OBJ) in dir(case.TreatmentPlans):
exists = True
return exists
def rayStationSave():
patient = None
try:
import connect
patient = connect.get_current(KEYNAME_PATIENT)
patient.Save() # need to do this so to avoid "PreConditionViolationException: State must be saved."
except:
pass # if there is no patient open
return patient
def getPatientAndPlan(planName, debug=False):
patient, case, plan, beamset = None, None, None, None
# Step 1 - Get patient
patient = rayStationSave()
if patient is None:
return patient, case, plan, beamset
case = patient.Cases[0]
# Step 2 - Get plan
if not checkForRTPlan(case, planName):
return patient, case, plan, beamset
plan = case.TreatmentPlans[planName]
beamset = plan.BeamSets[planName]
status = True
# Step 3 - Return
return patient, case, plan, beamset
def copyPlan(basePlanName, newPlanName, debug=False):
# Step 1 - Init
copyPlanStatus = False
# Step 2 - Boilerplate code for get patient and plans
patient, case, basePlan, _ = getPatientAndPlan(basePlanName)
patient, case, newPlan, _ = getPatientAndPlan(newPlanName)
if patient is None:
print (' - [ERROR][copyPlan()] No patient loaded')
return copyPlanStatus
if basePlan is None:
print (' - [ERROR][copyPlan()] No basePlan named {0} found'.format(basePlanName))
return copyPlanStatus
# Step 3 - Copy plan
if newPlan is None:
print (' - [INFO][copyPlan()] Copying plan {0} to {1}'.format(basePlanName, newPlanName))
case.CopyPlan(PlanName=basePlanName, NewPlanName=newPlanName, KeepBeamSetNames=False)
rayStationSave()
print (' - [INFO][copyPlan()] Copied plan: ', newPlanName)
arcBeamStatus = makeDualArcBeam(newPlanName)
if not arcBeamStatus:
print (' - [ERROR][copyPlan()] Failed to make dual arc beam')
return copyPlanStatus
rayStationSave()
else:
print (' - [WARNING][copyPlan()] Plan named {0} already exists'.format(newPlanName))
# Step 4 - Debug
if debug:
print (' - [INFO][copyPlan()] Setting current plan: ', newPlanName)
patient.Cases[0].SetCurrent()
patient.Cases[0].TreatmentPlans[newPlanName].SetCurrent()
copyPlanStatus = True
return copyPlanStatus
def makeDualArcBeam(planName):
print (' - [INFO][makeDualArcBeam()] Making dual arc beam for plan: ', planName)
try:
# Step 1 - Get basics
patient = connect.get_current(KEYNAME_PATIENT)
plan = patient.Cases[0].TreatmentPlans[planName]
beamset = plan.BeamSets[planName]
# Step 2 - Delete all existing beams
isoCenter = None
while len(beamset.Beams) != 0:
for beam in beamset.Beams:
isoCenter = beam.Isocenter.Position
beamset.DeleteBeam(BeamName=beam.Name)
print (' - [INFO][makeDualArcBeam()] isoCenter: ', isoCenter)
# Step 3 - Create new beam
if isoCenter is None:
return False
beamset.CreateDefaultIsocenterData(Position=isoCenter)
beam = beamset.CreateArcBeam(Name="01.01", Description="1 arc 178-182"
, GantryAngle=178, ArcStopGantryAngle=182, ArcRotationDirection="CounterClockwise"
, BeamQualityId="6"
, IsocenterData=beamset.CreateDefaultIsocenterData(Position=isoCenter)
, CouchRotationAngle=0, CouchPitchAngle=0, CouchRollAngle=0, CollimatorAngle=20
)
beam.SetBolus(BolusName="")
beam.SetDoseSpecificationPoint(Name='DSP')
# Step 4 - Settings for dual arc beam
plan.PlanOptimizations[0].OptimizationParameters.TreatmentSetupSettings[0].BeamSettings[0].ArcConversionPropertiesPerBeam.EditArcBasedBeamOptimizationSettings(CreateDualArcs=True
, FinalGantrySpacing=2, MaxArcDeliveryTime=90, BurstGantrySpacing=None, MaxArcMU=None
)
except:
traceback.print_exc()
pdb.set_trace()
return False
return True
if __name__ == "__main__":
copyPlan('1A OROFARKL', '1A OROFARKL-R1', debug=True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment