Has anyone imported IC Profiler PRS files into Pylinac and looked at how the flatness and symmetry calculations compare between the two pieces of software? It would appear that if I select ‘varian’ as the analysis protocol for both I -should- be getting the same results. I’m not sure if there’s a difference in how Pylinac is determining CAX, or the field size?
The code that we wrote seems to bring in the array values properly but the resulting calculation gives sometimes very different results. At times, the discrepancy is >0.7%, which seems large.
I included our code in the attachments. Note that it’s written to be used in QATrack+, hence the UTILS lines, etc.
As a follow up, I’m wondering if there is something weird with how the ‘field size’ is being determined. I plotted the x_lt and x_rt outputs (the third and fourth outputs of symmetry_calculations(x)) and it seems like at least one of them (x_rt) is way off. Any ideas?
As an update to everyone, I think the problem was due to the very sparse sampling nature of the IC Profiler. Prior to analysis I interpolated the data by a factor of 5 and I get much better agreement now.
I have just gone through the process of comparing my BeamScheme program against pylinac (and other programs) and got good agreement (with certain provisos). I think pylinac does not interpolate between points to find the field edge, however I still need to confirm this. For EPID images the error is not large, but for low resolution images from 2D arrays it can be up to a centimeter.
I am a bit swamped at the moment but I will try and have a look at your PRS file.
I’ve finally got to look at this. Pylinac is currently not using interpolation to determine field edges. If I load the attached file LowRes.dcm into FlatSym it incorrectly reports the field size as 85mm when it should be 80mm. If I enable interpolation in the code pylinac gives the correct field size as 80mm. If I look at the flattened area in the plot it is shifted to the right of the image probably due to the discretisation of the centre.
Having said that I see in your code that you have enabled interpolation for the calculation of your field size so I am surprised that your field size is incorrect. Perhaps there is something else we need to look at.
As far as the flatness and symmetry is concerned there are a couple of factors at play here. The first is that pylinac is probably working with a slightly different flattened area than your 2D array software. pylinac takes the data between 80% of the measured field edge irrespective of the detector centre. Most 2D arrays work symmetrically out from the centre detector and take 80% of the nominal field size. This means that pylinac may have included or left out points on the edge of the flattened area that the
2D array software may not have included or left out. As these point are generally in the ‘horns’ of the profile it can make quite a difference to the flatness.
Secondly, for the symmetry pylinac takes the points in the flattened area, makes an inverted copy and then subtracts or divides the one with the other. Again most arrays work symmetrically out from the central detector(s) even if they apply a CAX correction. This means that pylinac and your software are probably not comparing the same sets of points.
For high resolution images such as EPID these differences are very small, but for 2D arrays they can be quite large. I’m not quite sure what the solution is. If you want an exercise in frustration try comparing 2D arrays to each other or importing different 2D array data. @James what are your thoughts?
-Alan is correct that pylinac does not interpolate points for the flatsym analysis by default. As EPID images are the ideal target, interpolation was never a goal. Usually, arrays calculate F&S from the direct measurement points, not on interpolated points, so the behavior was meant to match that.
-pylinac profiles have the ability to use interpolation, but I regret the way it was implemented. If you look at the module, you have to call interpolate=True for any method you want to use interpolation on (and not all methods have this). This can lead to inconsistency if you perform multiple calculations but do not use the interpolation parameter consistently. In retrospect, I would have implemented something like this, where any subsequent method calls applied the interpolation consistently:
raw_profile = SingleProfile(…, interpolate=False)
interp_profile = SingleProfile(…, interpolate=True, interpolation_type=‘linear’)
-I must be an idiot because based on your code David it looks like you’re loading the .prs file but it doesn’t load into pylinac as it’s looking for a dicom file. Do you have a conversion script to convert .prs to DICOM or numpy array?