I’m using the PicketFence module to analyze our EPID-based picket fence images. Our plan uses picket positions centered on the origin, spaced every 15mm. I then use pf.pickets.dist2cax-PicketPositions to evaluate how far off the measured picket positions are from their planned positions:
for x in range(11):
PicketDiscrepancy = pf.pickets.dist2cax-PicketPositions
`
We do this for images acquired at the four cardinal gantry angles. The problem is, we’re getting some pretty bad results on some of our units for some angles, as bad as 2.8mm.
Some questions:
Have I coded this correctly to give me the information that I desire?
Is the IsoCal calibration reflected in dist2cax, or is it not represented? Would that be different on Clinacs and TrueBeams?
Is the correlation between planned and measured picket positions something that you would look at in your clinic? Why or why not? It doesn’t seem to be part of the DoseLab software that we previously used.
Here is the code for dist2cax:
` @property def dist2cax(self) → float: “”“The distance from the CAX to the picket, in mm.”“” center_fit = np.poly1d(self.fit) if self.settings.orientation == UP_DOWN: length = self.image.shape[0] else: length = self.image.shape[1] x_data = np.arange(length) y_data = center_fit(x_data) idx = int(round(len(x_data) / 2)) if self.settings.orientation == UP_DOWN: axis = ‘x’ p1 = Point(y_data[idx], x_data[idx]) else: axis = ‘y’ p1 = Point(x_data[idx], y_data[idx]) return (getattr(self.image.center, axis) - getattr(p1, axis)) * self.settings.mmpd
Considering it further, dist2cax is just finding the center of the image, right? So, it wouldn’t know, for example, about isocal on a Clinac, or if the EPID was shifted (intentionally or otherwise)?
Hi David,
Yes, dist2cax measures the distance to the geometric center of the image. I would need to brush up on exactly how IsoCal on Clinac works. It’s supposed to apply a virtual shift to the data, but it’s possible this is in a tag I haven’t seen/don’t use. Of course, this isn’t a problem on TrueBeam as the correction is to the imager itself.
Have you looked at the shift as a function of gantry angle? If the apparent shift correlated with what is expected (lateral shift at 90/270) then it would indeed be indicative of isocal not being taken into account.
I used XRayImageReceptorTranslation[1] because our collimator rotation is 90 degrees. I could have coded it better to check for collimator rotation first, but we have no plans to change our picket fence plans so I took the lazy way out.
All the values were positive? Interesting. Sweeping away the cobwebs I think I recall that g=0 is typically the best accuracy because that’s where it’s calibrated (minus isocal). The part I don’t get is why 180 is so high. Also, shouldn’t there be two offsets, one for x and one for y?