Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Relax bounding box requirements for model training #8222

Merged
merged 10 commits into from
Nov 28, 2024

Conversation

daniel-wer
Copy link
Member

@daniel-wer daniel-wer commented Nov 20, 2024

Remove requirements of bounding boxes to have the same x/y dimension as well as the same dimensions overall for model training. Needs https://github.com/scalableminds/voxelytics/pull/3796.

URL of deployed dev instance (used for testing):

  • https://___.webknossos.xyz

Steps to test:

  • Create an annotation with two differently sized bounding boxes.
  • Create two annotations each with one bounding box that are differently sized.
  • Locally execute yarn enable-jobs, open "AI Models" from the Administration pane. Trying to start a training using the one annotation as well as using the two annotations with differently sized bounding boxes should be allowed.

(Please delete unneeded items, merge only when none are left open)

@daniel-wer daniel-wer self-assigned this Nov 20, 2024
Copy link

coderabbitai bot commented Nov 20, 2024

📝 Walkthrough
📝 Walkthrough
📝 Walkthrough
📝 Walkthrough

Walkthrough

The pull request introduces modifications to the TrainAiModelFromAnnotationTab component in the train_ai_model.tsx file. Key changes include an updated alert message in the ExperimentalWarning component regarding bounding box size requirements and a significant overhaul of the bounding box validation logic. The function areInvalidBoundingBoxesIncluded has been replaced with checkBoundingBoxesForErrorsAndWarnings, enhancing error handling. The overall control flow and error reporting in the TrainAiModelTab function have also been adjusted to improve user experience during form submission.

Changes

File Path Change Summary
frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx - Updated alert message in ExperimentalWarning for bounding box size requirements.
- Replaced areInvalidBoundingBoxesIncluded with checkBoundingBoxesForErrorsAndWarnings for improved validation logic.
- Renamed and updated areInvalidAnnotationsIncluded to checkAnnotationsForErrorsAndWarnings for structured error reporting.
- Modified user bounding box handling to include annotation IDs.
CHANGELOG.unreleased.md - Updated changelog to include enhancements in remote URI handling, asynchronous image file reading, improved error messages, and removal of bounding box size restrictions for super users.
- Added new feature allowing training with varying bounding box sizes.
- Fixed several bugs and removed Google Analytics integration.

Possibly related PRs

Suggested labels

enhancement

Suggested reviewers

  • MichaelBuessemeyer
  • dieknolle3333

Poem

🐰 In the fields where the bounding boxes play,
A warning was changed to brighten the day.
No more checks for the sizes so tight,
Just hop along, everything's right!
With annotations added, we train with glee,
Simplified paths for all to see! 🌼


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (1)
frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx (1)

68-68: LGTM with a minor suggestion for clarity

The warning message accurately reflects the relaxed requirements. Consider adding an example for better clarity:

-      message="Please note that this feature is experimental. All bounding boxes should have equal dimensions or have dimensions which are multiples of the smallest bounding box. Ensure the size is not too small (we recommend at least 10 Vx per dimension) and choose boxes that represent the data well."
+      message="Please note that this feature is experimental. All bounding boxes should have equal dimensions or have dimensions which are multiples of the smallest bounding box (e.g., if smallest box is 10x10, others can be 10x10, 20x20, or 10x20). Ensure the size is not too small (we recommend at least 10 Vx per dimension) and choose boxes that represent the data well."
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 3c7700c and 735b15b.

📒 Files selected for processing (1)
  • frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx (2 hunks)
🔇 Additional comments (1)
frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx (1)

426-426: Verify impact on model training quality

The relaxed validation allows for more flexible bounding box configurations, but we should verify:

  1. That the training system can handle variable box sizes
  2. That model quality isn't negatively impacted
  3. That the test steps in the PR description cover all edge cases

areSomeBBoxesInvalid: true,
invalidBBoxesReason: "All bounding boxes must have the same size.",
};
return { areSomeBBoxesInvalid: false, invalidBBoxesReason: null };
Copy link

@coderabbitai coderabbitai bot Nov 20, 2024

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider adding basic size validations

While removing strict size equality checks aligns with the PR objective, consider adding basic validations to prevent training issues:

  1. Validate minimum box size (10 Vx per dimension)
  2. Validate that box dimensions are multiples of the smallest box
  3. Add debug logging of box dimensions for troubleshooting
   if (userBoundingBoxes.length === 0) {
     return {
       areSomeBBoxesInvalid: true,
       invalidBBoxesReason: "At least one bounding box must be defined.",
     };
   }
+  // Find smallest dimensions
+  const minDimensions = userBoundingBoxes.reduce(
+    (min, box) => ({
+      x: Math.min(min.x, box.boundingBox.width),
+      y: Math.min(min.y, box.boundingBox.height),
+      z: Math.min(min.z, box.boundingBox.depth),
+    }),
+    { x: Infinity, y: Infinity, z: Infinity }
+  );
+
+  // Validate minimum size and multiple requirements
+  const invalidBoxes = userBoundingBoxes.filter(box => {
+    const dims = box.boundingBox;
+    const tooSmall = dims.width < 10 || dims.height < 10 || dims.depth < 10;
+    const notMultiple = 
+      dims.width % minDimensions.x !== 0 ||
+      dims.height % minDimensions.y !== 0 ||
+      dims.depth % minDimensions.z !== 0;
+    return tooSmall || notMultiple;
+  });
+
+  if (invalidBoxes.length > 0) {
+    return {
+      areSomeBBoxesInvalid: true,
+      invalidBBoxesReason: `Some bounding boxes are either too small (min 10 Vx) or not multiples of the smallest box dimensions (${minDimensions.x}x${minDimensions.y}x${minDimensions.z})`
+    };
+  }
+
+  // Log dimensions for debugging
+  console.debug('Bounding box dimensions:', userBoundingBoxes.map(box => ({
+    width: box.boundingBox.width,
+    height: box.boundingBox.height,
+    depth: box.boundingBox.depth
+  })));
+
   return { areSomeBBoxesInvalid: false, invalidBBoxesReason: null };

Committable suggestion skipped: line range outside the PR's diff.

Copy link
Contributor

Choose a reason for hiding this comment

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

@daniel-wer Maybe these good suggestions:

  • Validate minimum box size (10 Vx per dimension)
  • Validate that box dimensions are multiples of the smallest box

Maybe showing a warning in the form (afaik antd supports this), making the from still submittable but also showing the user potential issues with the training data up front.
I'd let this for you to decide whether to add this in this pr :)

Copy link

Choose a reason for hiding this comment

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

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (1)
CHANGELOG.unreleased.md (1)

20-20: LGTM with a minor suggestion for clarity.

The changelog entry accurately describes the changes and includes helpful recommendations. Consider slightly rewording for better clarity:

-Allowed to train an AI model using differently sized bounding boxes. We recommend all bounding boxes to have equal dimensions or to have dimensions which are multiples of the smallest bounding box.
+Added support for training AI models with differently sized bounding boxes. For optimal results, we recommend using bounding boxes with either equal dimensions or dimensions that are multiples of the smallest bounding box.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 735b15b and 985e1b7.

📒 Files selected for processing (1)
  • CHANGELOG.unreleased.md (1 hunks)

Copy link
Contributor

@MichaelBuessemeyer MichaelBuessemeyer left a comment

Choose a reason for hiding this comment

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

Thanks for this pr 🙏

Besides my comment regarding the AI's suggestion I found nothing :)

Feel free to merge with or without the improved handling of sub-optimal training bounding boxes :)

areSomeBBoxesInvalid: true,
invalidBBoxesReason: "All bounding boxes must have the same size.",
};
return { areSomeBBoxesInvalid: false, invalidBBoxesReason: null };
Copy link
Contributor

Choose a reason for hiding this comment

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

@daniel-wer Maybe these good suggestions:

  • Validate minimum box size (10 Vx per dimension)
  • Validate that box dimensions are multiples of the smallest box

Maybe showing a warning in the form (afaik antd supports this), making the from still submittable but also showing the user potential issues with the training data up front.
I'd let this for you to decide whether to add this in this pr :)

… errors and warnings more prominent by using Alerts. Include annotation ID and topleft + size for offending boxes.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (1)
frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx (1)

489-503: Replace map with forEach since the return value is unused.

The map function is being used for its side effects only, which is not ideal.

-  userBoundingBoxes.map(({ boundingBox: box, annotationId }) => {
+  userBoundingBoxes.forEach(({ boundingBox: box, annotationId }) => {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 985e1b7 and 7d7945c.

📒 Files selected for processing (2)
  • CHANGELOG.unreleased.md (1 hunks)
  • frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • CHANGELOG.unreleased.md
🔇 Additional comments (4)
frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx (4)

69-70: LGTM! Clear and informative alert message.

The updated alert message effectively communicates the new requirements while providing helpful guidance about bounding box dimensions.


220-225: LGTM! Good enhancement to bounding box tracking.

The addition of annotation IDs to bounding boxes improves traceability and error reporting capabilities.


459-483: LGTM! Robust bounding box validation logic.

The validation logic effectively implements the new requirements while maintaining good checks for minimum dimensions.


347-374: LGTM! Well-structured error and warning display.

The UI effectively distinguishes between errors (blocking) and warnings (non-blocking), providing a good user experience while maintaining data quality.

@daniel-wer
Copy link
Member Author

@MichaelBuessemeyer Thanks for the review. I opted to refactor the error display mechanism and include warnings as well. This turned out to be a bit more involved, but I think the result is more user friendly. Please have a look at my latest commit. See this screenshot, but feel free to test yourself as well :)

image

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (3)
frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx (3)

231-242: Consider enhancing error messages with actionable guidance

While the error/warning separation is well-implemented, consider adding specific remediation steps to help users resolve issues more effectively.

 const { hasAnnotationErrors, errors: annotationErrors } =
   checkAnnotationsForErrorsAndWarnings(annotationInfos);
 const {
   hasBBoxErrors,
   hasBBoxWarnings,
   errors: bboxErrors,
   warnings: bboxWarnings,
 } = checkBoundingBoxesForErrorsAndWarnings(userBoundingBoxes);
 const hasErrors = hasAnnotationErrors || hasBBoxErrors;
 const hasWarnings = hasBBoxWarnings;
-const errors = [...annotationErrors, ...bboxErrors];
-const warnings = bboxWarnings;
+const errors = [...annotationErrors, ...bboxErrors].map(error => 
+  `${error}\nTo fix this: Check the annotation settings and ensure all required bounding boxes are properly defined.`
+);
+const warnings = bboxWarnings.map(warning =>
+  `${warning}\nRecommendation: Consider adjusting the bounding box dimensions to match the suggested criteria.`
+);

377-385: Enhance tooltip message specificity

Consider providing more specific guidance in the tooltip when the form is disabled.

-        <Tooltip title={hasErrors ? "Solve the errors displayed above before continuing." : ""}>
+        <Tooltip title={hasErrors ? "Please address all validation errors above. Each error must be resolved before training can begin." : "Click to start the model training process"}>

476-483: Consider optimizing dimension calculation

The current implementation recalculates dimensions for each box. Consider memoizing the results for better performance with large datasets.

+  const getDimensions = React.useMemo(() => (box: Vector6) => ({
+    x: box.max[0] - box.min[0],
+    y: box.max[1] - box.min[1],
+    z: box.max[2] - box.min[2],
+  }), []);
+
   const minDimensions = userBoundingBoxes.reduce(
-    (min, { boundingBox: box }) => ({
-      x: Math.min(min.x, box.max[0] - box.min[0]),
-      y: Math.min(min.y, box.max[1] - box.min[1]),
-      z: Math.min(min.z, box.max[2] - box.min[2]),
-    }),
+    (min, { boundingBox: box }) => {
+      const dims = getDimensions(box);
+      return {
+        x: Math.min(min.x, dims.x),
+        y: Math.min(min.y, dims.y),
+        z: Math.min(min.z, dims.z),
+      };
+    },
     { x: Number.POSITIVE_INFINITY, y: Number.POSITIVE_INFINITY, z: Number.POSITIVE_INFINITY },
   );
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 7d7945c and 103dc38.

📒 Files selected for processing (1)
  • frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx (6 hunks)
🔇 Additional comments (2)
frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx (2)

69-70: LGTM: Improved warning message clarity

The updated message better communicates the relaxed requirements while maintaining helpful guidance about recommended dimensions.


220-225: LGTM: Enhanced bounding box tracking

Good enhancement to include annotationId with each bounding box, enabling more precise error reporting and validation.

frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx Outdated Show resolved Hide resolved
Copy link
Contributor

@MichaelBuessemeyer MichaelBuessemeyer left a comment

Choose a reason for hiding this comment

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

Nice, looks very good.

I only found potential mini improvements for the messages.
Please note that I did not test starting an AI job with multiple annotations as I don't know how and your screenshots already shows that it seems to work :)

I'd say this is ready to got; with or without the minor improvements I suggested

const arrayBox = computeArrayFromBoundingBox(box);
const [_x, _y, _z, width, height, depth] = arrayBox;
if (width < 10 || height < 10 || depth < 10) {
tooSmallBoxes.push({ boundingBox: arrayBox, annotationId });
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd say it would be very helpful to include the bounding box name in the warning (it needs to be included in the pushed object here)
A list like

133, 115, 128, 64, 60, 25 (6745e0d1660100dd04d88932)
34, 162, 128, 82, 71, 32 (6745e0d1660100dd04d88932)
70, 79, 128, 1, 79, 46 (6745e0d1660100dd04d88932)

is not very useful. One might be able to find the bounding box listed in the waring by name much easier. I could imagine a list kinda like this:

Bounding box 1: 133, 115, 128, 64, 60, 25 (6745e0d1660100dd04d88932)
Bounding box 2: 34, 162, 128, 82, 71, 32 (6745e0d1660100dd04d88932)
Bounding box 4: 70, 79, 128, 1, 79, 46 (6745e0d1660100dd04d88932)

I am not sure whether that's the best way to include the bbox name somewhere. So feel free to do it the way you prefer.

Copy link
Member Author

Choose a reason for hiding this comment

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

Great point 🙏

frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx Outdated Show resolved Hide resolved
@daniel-wer
Copy link
Member Author

Thanks for the feedback, this is what the warnings look like now:

image

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Outside diff range and nitpick comments (2)
frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx (2)

231-242: Consider separating error/warning state management

The error and warning state management logic could be extracted into a custom hook for better reusability and separation of concerns.

+function useErrorWarningState(annotationInfos: any[], userBoundingBoxes: any[]) {
+  const { hasAnnotationErrors, errors: annotationErrors } =
+    checkAnnotationsForErrorsAndWarnings(annotationInfos);
+  const {
+    hasBBoxErrors,
+    hasBBoxWarnings,
+    errors: bboxErrors,
+    warnings: bboxWarnings,
+  } = checkBoundingBoxesForErrorsAndWarnings(userBoundingBoxes);
+  
+  return {
+    hasErrors: hasAnnotationErrors || hasBBoxErrors,
+    hasWarnings: hasBBoxWarnings,
+    errors: [...annotationErrors, ...bboxErrors],
+    warnings: bboxWarnings,
+  };
+}

508-513: Consider adding dimension details to the warning message

The warning message for small boxes could be more informative by including the minimum required dimensions.

     warnings.push(
-      `The following bounding boxes are not at least 10 Vx in each dimension which is suboptimal for the training:\n${tooSmallBoxesStrings.join("\n")}`,
+      `The following bounding boxes are smaller than the minimum required dimensions (10 x 10 x 10 Vx) which is suboptimal for the training:\n${tooSmallBoxesStrings.join("\n")}`,
     );
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 103dc38 and 177c890.

📒 Files selected for processing (2)
  • CHANGELOG.unreleased.md (1 hunks)
  • frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • CHANGELOG.unreleased.md
🔇 Additional comments (4)
frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx (4)

69-70: LGTM: Clear and informative warning message

The updated warning message effectively communicates the requirements and recommendations for bounding box dimensions.


220-225: LGTM: Improved type safety with annotationId

The mapping of user bounding boxes now includes the annotationId, which enhances type safety and traceability.


347-374: LGTM: Well-structured error and warning display

The error and warning alerts are well-organized with appropriate styling and icons. The use of whiteSpace: "pre-line" ensures proper formatting of multi-line messages.


505-507: LGTM: Clear and informative box formatting

The boxWithIdToString helper function provides a clear and consistent format for displaying bounding box information.

Comment on lines +489 to +503
userBoundingBoxes.forEach(({ boundingBox: box, name, annotationId }) => {
const arrayBox = computeArrayFromBoundingBox(box);
const [_x, _y, _z, width, height, depth] = arrayBox;
if (width < 10 || height < 10 || depth < 10) {
tooSmallBoxes.push({ boundingBox: arrayBox, name, annotationId });
}

if (
width % minDimensions.x !== 0 ||
height % minDimensions.y !== 0 ||
depth % minDimensions.z !== 0
) {
nonMultipleBoxes.push({ boundingBox: arrayBox, name, annotationId });
}
});
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider early return for invalid dimensions

The validation loop should return early if any box has invalid dimensions (zero or negative) to prevent unnecessary processing.

   userBoundingBoxes.forEach(({ boundingBox: box, name, annotationId }) => {
     const arrayBox = computeArrayFromBoundingBox(box);
     const [_x, _y, _z, width, height, depth] = arrayBox;
+    // Check for invalid dimensions
+    if (width <= 0 || height <= 0 || depth <= 0) {
+      tooSmallBoxes.push({ boundingBox: arrayBox, name, annotationId });
+      return;
+    }
+
     if (width < 10 || height < 10 || depth < 10) {
       tooSmallBoxes.push({ boundingBox: arrayBox, name, annotationId });
     }

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +476 to +483
const minDimensions = userBoundingBoxes.reduce(
(min, { boundingBox: box }) => ({
x: Math.min(min.x, box.max[0] - box.min[0]),
y: Math.min(min.y, box.max[1] - box.min[1]),
z: Math.min(min.z, box.max[2] - box.min[2]),
}),
{ x: Number.POSITIVE_INFINITY, y: Number.POSITIVE_INFINITY, z: Number.POSITIVE_INFINITY },
);
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider adding validation for zero or negative dimensions

While the code handles minimum size checks, it should also validate for zero or negative dimensions to prevent potential issues.

   const minDimensions = userBoundingBoxes.reduce(
     (min, { boundingBox: box }) => ({
+      // Validate that dimensions are positive
+      x: box.max[0] <= box.min[0] ? Infinity : Math.min(min.x, box.max[0] - box.min[0]),
+      y: box.max[1] <= box.min[1] ? Infinity : Math.min(min.y, box.max[1] - box.min[1]),
+      z: box.max[2] <= box.min[2] ? Infinity : Math.min(min.z, box.max[2] - box.min[2]),
-      x: Math.min(min.x, box.max[0] - box.min[0]),
-      y: Math.min(min.y, box.max[1] - box.min[1]),
-      z: Math.min(min.z, box.max[2] - box.min[2]),
     }),
     { x: Number.POSITIVE_INFINITY, y: Number.POSITIVE_INFINITY, z: Number.POSITIVE_INFINITY },
   );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const minDimensions = userBoundingBoxes.reduce(
(min, { boundingBox: box }) => ({
x: Math.min(min.x, box.max[0] - box.min[0]),
y: Math.min(min.y, box.max[1] - box.min[1]),
z: Math.min(min.z, box.max[2] - box.min[2]),
}),
{ x: Number.POSITIVE_INFINITY, y: Number.POSITIVE_INFINITY, z: Number.POSITIVE_INFINITY },
);
const minDimensions = userBoundingBoxes.reduce(
(min, { boundingBox: box }) => ({
// Validate that dimensions are positive
x: box.max[0] <= box.min[0] ? Infinity : Math.min(min.x, box.max[0] - box.min[0]),
y: box.max[1] <= box.min[1] ? Infinity : Math.min(min.y, box.max[1] - box.min[1]),
z: box.max[2] <= box.min[2] ? Infinity : Math.min(min.z, box.max[2] - box.min[2]),
}),
{ x: Number.POSITIVE_INFINITY, y: Number.POSITIVE_INFINITY, z: Number.POSITIVE_INFINITY },
);

Copy link
Contributor

@MichaelBuessemeyer MichaelBuessemeyer left a comment

Choose a reason for hiding this comment

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

Very Awesome

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (3)
frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx (3)

220-225: Consider adding type guard for annotation id access.

The current type casting approach for accessing the annotation id could be made more type-safe.

Consider this safer approach:

-      annotationId: "id" in annotation ? annotation.id : annotation.annotationId,
+      annotationId: isHybridTracing(annotation) ? annotation.id : annotation.annotationId,

Where isHybridTracing is a type guard:

function isHybridTracing(annotation: HybridTracing | APIAnnotation): annotation is HybridTracing {
  return 'id' in annotation;
}

492-494: Consider extracting magic numbers into named constants.

The minimum dimension size of 10 Vx is used as a magic number. This value appears to be an important threshold for the training process.

Consider extracting it into a named constant:

+const MIN_BOUNDING_BOX_DIMENSION = 10; // Voxels
+
 if (width < 10 || height < 10 || depth < 10) {
-  tooSmallBoxes.push({ boundingBox: arrayBox, name, annotationId });
+  if (width < MIN_BOUNDING_BOX_DIMENSION || 
+      height < MIN_BOUNDING_BOX_DIMENSION || 
+      depth < MIN_BOUNDING_BOX_DIMENSION) {
+    tooSmallBoxes.push({ boundingBox: arrayBox, name, annotationId });
+  }

476-483: Consider validating dimensions before reduction.

The current implementation might attempt to calculate minimum dimensions even if some boxes have invalid (zero or negative) dimensions.

Consider adding validation before reduction:

+  // Validate dimensions are positive
+  const invalidDimensions = userBoundingBoxes.find(({ boundingBox: box }) => {
+    const width = box.max[0] - box.min[0];
+    const height = box.max[1] - box.min[1];
+    const depth = box.max[2] - box.min[2];
+    return width <= 0 || height <= 0 || depth <= 0;
+  });
+
+  if (invalidDimensions) {
+    return {
+      hasBBoxErrors: true,
+      hasBBoxWarnings: false,
+      errors: ["All bounding box dimensions must be positive"],
+      warnings: [],
+    };
+  }
+
   const minDimensions = userBoundingBoxes.reduce(
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 177c890 and 221af60.

📒 Files selected for processing (2)
  • CHANGELOG.unreleased.md (1 hunks)
  • frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • CHANGELOG.unreleased.md
🔇 Additional comments (1)
frontend/javascripts/oxalis/view/jobs/train_ai_model.tsx (1)

69-70: LGTM! Clear and informative warning message.

The updated message effectively communicates the relaxed requirements while still providing helpful guidance about bounding box dimensions.

@bulldozer-boy bulldozer-boy bot merged commit db31a50 into master Nov 28, 2024
3 checks passed
@bulldozer-boy bulldozer-boy bot deleted the relax-train-model-bbox-requirements branch November 28, 2024 14:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants