Closed thenineteen closed 3 years ago
once I've done this for QUERY_LATERALISATION, I will let @fepegar know as we will need an updated API to allow for the setting to change as a checkbox: could call it "use global lateralising value".
ideally when this box is ticked it says "using global lateralising value" and if unticked (default), it says "using individual patient-level lateralising value"
Is there anything to do for me atm? Seems like I need to wait until you implement this for QUERY_LATERALISATION
.
nothing for you to do yet, as I haven't done this.
what's the best way for the API. I think it is best I write an entirely separate QUERY_LAT_GLOBAL module or function. Will that work for you?
probably related to pull return query statistics
#108 and slicer log should not need to be opened
#83
If we return the global lateralising values as proportions for each query and can display it as a lateralising bar on the coronals and axials, then this issue will also be resolved.
instead of another user tick box option as suggested above, it would be best to have the global lateralising proportion visible on all queries either as a percentage and/or color-bar as in #55
the display could show raw numbers in a table, similar to the GIF parcellation numbers, this is the aim:
how do we get there... using below pseudocode:
# output to show global lateralisation: note this section is already in semiology.py
# note that if the user doesn't determine a dominant hemisphere and doens't determine a latealising semiology (symptoms or sign)...
# ...then there is no lateralising R or L proportion. Whereas if we have all the info, we can just display e.g. 70% right.
# Otherwise, we only display the raw numbers/proportions: CL, IL, DomH and NonDomH
# as per query_lateralisation() in semiology module which calls:
all_combined_gifs, num_QL_lat, num_QL_CL, num_QL_IL, num_QL_BL, num_QL_DomH, num_QL_NonDomH = \
QUERY_LATERALISATION(
query_semiology_result,
self.data_frame,
map_df_dict,
gif_lat_file,
side_of_symptoms_signs=self.symptoms_side.value,
pts_dominant_hemisphere_R_or_L=self.dominant_hemisphere.value,
)
next we can use the returned values to make the above table.
In addition, if we know symptoms side or dominance, we can show the proportion lateralising to the left hemisphere:
Right = 0
Left = 0
# could skip the if statement but it's here to make the logic clear
if self.symptoms_side.value != Laterality.Neutral (alternatively is equal to Laterality.Right or Laterality.Left) OR self.dominant_hemisphere.value != Laterality.Neutral:
# pt input
if side_of_symptoms_signs == 'R':
Right += num_QL_IL
Left += num_QL_CL
elif side_of_symptoms_signs == 'L':
Right += num_QL_CL
Left += num_QL_IL
if pts_dominant_hemisphere_R_or_L:
if pts_dominant_hemisphere_R_or_L == 'R':
Right += num_QL_DomH
Left += num_QL_NonDomH
elif pts_dominant_hemisphere_R_or_L == 'L':
Right += num_QL_NonDomH
Left += num_QL_DomH
# now add extra info to the output table above or show as a horizontal bar indicator on axial/coronal slices:
If Right != 0 and Left != 0:
Left_Percentage = Left*100/(Left+Right)
Right_Percentage = Right*100/(Left+Right)
# preferably only show the larger one as both is redundant
This will change the semiology
API, which is used to connect mega_analysis
and 3D Slicer. The changes will break some tests. I'll open a PR and then I can work on the Slicer stuff and you can remove the tests if you like (they should be used to test lower-level elements anyway).
How would you compute the table from 2 semiologies?
This will change the
semiology
API, which is used to connectmega_analysis
and 3D Slicer. The changes will break some tests. I'll open a PR and then I can work on the Slicer stuff and you can remove the tests if you like (they should be used to test lower-level elements anyway).
I was hoping we implement this as an feature on top of the current output, not instead of, so it doesn't change what we currently see in slicer table or 3D brain, and all tests still pass as its the same output as before, plus a global lateralising %?
How would you compute the table from 2 semiologies?
I'm going to answer this Q in my next comment below:
As you have modified the output of QUERY_LATERALISATION
, this is the only way I can see to propagate the lateralising data points information from the Semiology
class to the output of the query.
I think in most tests you could just replace heatmap =
with heatmap, _ =
.
... next we can use the returned values to make the above table.
In addition, if we know symptoms side or dominance, we can show the proportion lateralising to the left hemisphere:
Right = 0 Left = 0 # could skip the if statement but it's here to make the logic clear if self.symptoms_side.value != Laterality.Neutral (alternatively is equal to Laterality.Right or Laterality.Left) OR self.dominant_hemisphere.value != Laterality.Neutral: # pt input if side_of_symptoms_signs == 'R': Right += num_QL_IL Left += num_QL_CL elif side_of_symptoms_signs == 'L': Right += num_QL_CL Left += num_QL_IL if pts_dominant_hemisphere_R_or_L: if pts_dominant_hemisphere_R_or_L == 'R': Right += num_QL_DomH Left += num_QL_NonDomH elif pts_dominant_hemisphere_R_or_L == 'L': Right += num_QL_NonDomH Left += num_QL_DomH # now add extra info to the output table above or show as a horizontal bar indicator on axial/coronal slices: If Right != 0 and Left != 0: Left_Percentage = Left*100/(Left+Right) Right_Percentage = Right*100/(Left+Right) # preferably only show the larger one as both is redundant
So this was how to calculate the global lateralising proportions for a single semiology.
To do the same for n number of semiologies: S1, S2, ...Sn
There are two strategies which would be nice to have side by side as the second gives us a CI for combinations:
1. equal lateralising % weights: where i goes from 1 to n
Left_Percentage = np.mean([Left_Percentage(Si)])
Right_Percentage = 100 - Left_Percentage # equivalent to Right_Percentage = np.mean(Right_Percentage (Si))
this would give an average lateralising percentage, which would help mitigate bias for less frequently occurring semiologies. Then to calculate confidence intervals we need a meta-analysis with inverse variance weighting
2. Pooling raw individual lateralising data with CI:
def pooling_raw_individual_lateralising_data():
Left_Sum = np.sum([Left(Si)])
Right_Sum = np.sum([Right(Si)])
n = (Left_Sum +Right_Sum )
Left_Proportion = Left_Sum / n
Left_Percentage_Total = Left_Proportion * 100
Confidence_Interval_95 = [
100* (Left_Proportion - 1.96* np.sqrt( Left_Proportion * (1 - Left_Proportion ) / n )),
100* (Left_Proportion + 1.96* np.sqrt( Left_Proportion * (1 - Left_Proportion ) / n )),
]
return Left_Percentage_Total, str(Confidence_Interval_95)
as a side note memo: Prof Williams recommended this for CI - will compare with python versions. also note at this point this is for both latealising and localising proportions, and not at the study level, but at the semiology level
currently, per individual study and patients, each semiology localisation gif parcellation is updated with a for loop in QUERY_LATERALISATION using the lateralising information.
There should be an option to force QUERY_LATERALISATION to map all the localisations first, then simply scale ALL OF THE GIFS using the few lateralising datapoints. This will also address the logging.debug the issue of: