Skip to content

461 log normalization method#462

Open
Elena-kal wants to merge 2 commits into
devfrom
461-log-normalization-method
Open

461 log normalization method#462
Elena-kal wants to merge 2 commits into
devfrom
461-log-normalization-method

Conversation

@Elena-kal

@Elena-kal Elena-kal commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Description

fixes #461
Adds another version of the normalization by median method.

Changes

Made changes to the method, added option to choose the method in forms and added and adapted tests.

Testing

Create a standard workflow, run it with checking the box. Switch the order and run it without checking the box.

PR checklist

Development

  • If necessary, I have updated the documentation (README, docstrings, etc.)
  • If necessary, I have created / updated tests.

Mergeability

  • main-branch has been merged into local branch to resolve conflicts
  • The tests and linter have passed AFTER local merge
  • The backend code has been formatted with black
  • The frontend code has been formatted with pnpm format and checked with pnpm lint

Code review

  • I have self-reviewed my code.
  • At least one other developer reviewed and approved the changes

@Elena-kal Elena-kal requested review from 3dot141592, jorisfu and tE3m July 8, 2026 16:40
@Elena-kal Elena-kal self-assigned this Jul 8, 2026
@Elena-kal Elena-kal removed the request for review from jorisfu July 8, 2026 16:40
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

Coverage report

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  backend/protzilla/data_preprocessing
  normalisation.py
  backend/protzilla/methods
  data_preprocessing.py 688
Project Total  

This report was generated by python-coverage-comment-action

@tE3m tE3m left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One larger question regarding the execution of the correction, apart from that just some nitpicks that are up to you. Solid work overall, I would've forgotten about the runner

# without adding the global median our data would be zero centered and therefore one half would be
# negative which can lead to problems later down the workflow
df_sample[f"Normalised {intensity_name}"] = (
df_sample[intensity_name] - quantile + global_median

@tE3m tE3m Jul 12, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm assuming you did, but just to be certain: this is the behavior Chris wants for the normalization?
I tried changing the order (first doing the median normalization and then log-transformation) and the result:

Image

is the same as if we didn't correct for the global median during the normalization (i.e. df_sample[intensity_name] - quantile instead of df_sample[intensity_name] - quantile + global_median):

Image

Just for reference, this is the output with correction enabled:
Image

So if this is the behavior Chris wants ("the users should know this"), I feel there should at least be a warning (or another checkbox). These steps being non-commutative would be surprising to me as a user

intensity_name
].div(quantile)
else:
df_sample[f"Normalised {intensity_name}"] = 0

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick, code style: feels like the column name could be extracted to its own variable, the f-string definition is repeated for every of the 4 cases

Comment on lines +687 to +692
if self.form["log"].value:
self.form["visual_transformation"].value = (
VisualTransformations.LINEAR.value
)
elif not self.form["log"].value:
self.form["visual_transformation"].value = VisualTransformations.LOG10.value

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick, code style: two comments on this - I always feel that it's more legible to first define the form fields as variables in the modifiy_form methods. Secondly, since the enums are StrEnum instances, there's no need to access .value - VisualTransformations.LOG10 == VisualTransformations.LOG10.value is True.
Both non-critical and up to you, added a proposal for convenience

Suggested change
if self.form["log"].value:
self.form["visual_transformation"].value = (
VisualTransformations.LINEAR.value
)
elif not self.form["log"].value:
self.form["visual_transformation"].value = VisualTransformations.LOG10.value
visual_transformation_field: DropdownField = self.form["visual_transformation"]
log_field: CheckboxField = self.form["log"]
if log_field.value:
visual_transformation_field.value = (
VisualTransformations.LINEAR
)
elif not log_field.value:
visual_transformation_field.value = VisualTransformations.LOG10

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants