-
Notifications
You must be signed in to change notification settings - Fork 4
feat: intensitysensor #653
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
base: main
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #653 +/- ##
==========================================
- Coverage 89.03% 85.87% -3.16%
==========================================
Files 39 39
Lines 5581 5870 +289
==========================================
+ Hits 4969 5041 +72
- Misses 612 829 +217 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
return False | ||
|
||
@nearfield.setter | ||
def nearfield(self, value): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if using property/setter methods, you will need to call the responding parameters setter methods as well.
i.e. for near field as true, then you need set call distance and cell diameter as well.
otherwise, the default setting will not happen.
self.x_sampling = 180 | ||
|
||
@property | ||
def x_start(self) -> float: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
then x_start will be shown in the auto-completion methods list even the orientation is set as conoscopic.... I am not sure if this is good...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes butt you can't set it and it will return none if the sensor is in conoscopic mode
change from cell integration angle to cell diameter rename theta_max_sampling
add default values for nearfield sub elements
By default, ``0.3491`` | ||
""" | ||
if self.nearfield: | ||
diameter = self.cell_distance * np.tan( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
diameter = self.cell_distance * np.tan( | |
diameter = 2* self.cell_distance * np.tan( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think that needs to be changed like that
return False | ||
|
||
@nearfield.setter | ||
def nearfield(self, value): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing docstring :)
raise TypeError("Sensor position is not in nearfield") | ||
|
||
@property | ||
def cell_diameter(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to keep the cell_diameter?
It implies to transform cell_integration_angle and cell_distance to get it. Whereas this kind of operation could be done by the customer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Speos Ui only has Celld iameter
if type(self._type) is str: | ||
return self._type | ||
elif isinstance(self._type, BaseSensor.Colorimetric): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if type(self._type) is str: | |
return self._type | |
elif isinstance(self._type, BaseSensor.Colorimetric): | |
if isinstance(self._type, BaseSensor.Colorimetric): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(sugg) Because the else will do exactly same as the first if
) | ||
return self._type | ||
|
||
def set_layer_type_none(self) -> SensorRadiance: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def set_layer_type_none(self) -> SensorRadiance: | |
def set_layer_type_none(self) -> SensorXMPIntensity: |
self, | ||
) -> Union[ | ||
None, | ||
SensorIrradiance, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is not correct, but I don't know why it is here.
SensorIrradiance, |
SensorIrradiance, | ||
BaseSensor.LayerTypeFace, | ||
BaseSensor.LayerTypeSequence, | ||
BaseSensor.LayerTypeIncidenceAngle, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No LayerTypeIncidenceAngle for Intensity sensor
BaseSensor.LayerTypeIncidenceAngle, |
ansys.speos.core.sensor.SensorIrradiance,\ | ||
ansys.speos.core.sensor.BaseSensor.LayerTypeFace,\ | ||
ansys.speos.core.sensor.BaseSensor.LayerTypeSequence,\ | ||
ansys.speos.core.sensor.BaseSensor.LayerTypeIncidenceAngle\ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ansys.speos.core.sensor.SensorIrradiance,\ | |
ansys.speos.core.sensor.BaseSensor.LayerTypeFace,\ | |
ansys.speos.core.sensor.BaseSensor.LayerTypeSequence,\ | |
ansys.speos.core.sensor.BaseSensor.LayerTypeIncidenceAngle\ | |
ansys.speos.core.sensor.BaseSensor.LayerTypeFace,\ | |
ansys.speos.core.sensor.BaseSensor.LayerTypeSequence,\ |
] | ||
Instance of Layertype Class for this sensor feature | ||
""" | ||
return self._layer_type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then what is returned when layer type is None, or Source?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess it could be harmonized like it is done for the type
-> property type
-> properties spectral and colorimetric
def x_end(self) -> float: | ||
"""The maximum value on x-axis (deg). | ||
By default, ``45``. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am wondering if a getter is the correct place to indicate default value.
@StefanThoene I see clearly how you want to use the properties. My only concern is the following: The decision is not only on my side. BUT, this is a really good feature to try this, you are right. Thanks a lot for you work |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here are some comments. The comments on "return None" and "const variable" are echoed multiple times but I've stopped doing it and some cases are not highlighted by the review. Please have a look though :)
Concerning the use of property, I'm clearly approving this approach. As I said before, correct use of property improves readability and user experience. Speaking as a Python user, this is something common in Python packages and it is strongly leveraged in other PyAnsys packages. @echambla If there is a reason to focus on fluent API please contact me so that you can clarify that topic to me
"""Property containing if the sensor is positioned in nearfield or infinity.""" | ||
if self._sensor_template.intensity_sensor_template.HasField("near_field"): | ||
return True | ||
else: | ||
return False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"""Property containing if the sensor is positioned in nearfield or infinity.""" | |
if self._sensor_template.intensity_sensor_template.HasField("near_field"): | |
return True | |
else: | |
return False | |
"""Return True if the sensor is positioned in nearfield, otherwise False.""" | |
return self._sensor_template.intensity_sensor_template.HasField("near_field") |
I'm guessing that HasField returns a boolean. If not, ignore this comment :)
self.cell_distance = 10 | ||
self.cell_diameter = 0.3491 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you define CELL_DISTANCE
and CELL_DIAMETER
at the beginning of the file and leverage it in the file (both code and docs) ? That will help you with maintenance and testing since changing the value in a single place will be applyed everywhere the "constant" variable is imported and used.
self.cell_diameter = 0.3491 | ||
else: | ||
if self._sensor_template.intensity_sensor_template.HasField("near_field"): | ||
self._sensor_template.intensity_sensor_template.ClearField("near_field") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be worth to warn your user if HasField("near_field")
is False
? Otherwise you can just use elif
right ?
def cell_distance(self): | ||
"""Distance of the Detector to origin in mm. | ||
By default, ``10`` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cf const var
if self.nearfield: | ||
return self._sensor_template.intensity_sensor_template.near_field.cell_distance | ||
else: | ||
return None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if self.nearfield: | |
return self._sensor_template.intensity_sensor_template.near_field.cell_distance | |
else: | |
return None | |
if self.nearfield: | |
return self._sensor_template.intensity_sensor_template.near_field.cell_distance |
Not sure the else is needed. By default python returns None
if nothing is returned
self._set_default_dimension_values() | ||
|
||
def set_viewing_direction_from_source(self): | ||
"""Set viewing direction from Source Looking At Sensor.""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"""Set viewing direction from Source Looking At Sensor.""" | |
"""Set viewing direction from source looking at sensor.""" |
self._sensor_template.intensity_sensor_template.from_source_looking_at_sensor.SetInParent() | ||
|
||
def set_viewing_direction_from_sensor(self): | ||
"""Set viewing direction from Sensor Looking At Source.""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"""Set viewing direction from Sensor Looking At Source.""" | |
"""Set viewing direction from sensor looking at source.""" |
def x_start(self) -> float: | ||
"""The minimum value on x-axis (deg). | ||
By default, ``45``. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
echo const var
""" | ||
template = self._sensor_template.intensity_sensor_template | ||
if template.HasField("intensity_orientation_conoscopic"): | ||
return None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you log a warning here if that's not something that should be used with conoscopic ?
@pluAtAnsys If you really want to avoid that kind of behavior, you could create specific classes for x_as_parallel and conoscopic ? Each would inherit from SensorXMPIntensity and have a subset of dedicated properties. Note that this would start to be verbose if you want to move your sensor from X to Conoscopic.
else: | ||
raise TypeError("Only Conoscopic Sensor has theta_max dimension") | ||
|
||
def set_type_photometric(self) -> SensorXMPIntensity: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wondering if set_type_photometric
, set_type_colorimetric
, set_type_radiometric
, set_type_spectral
, set_layer_type_none
, set_layer_type_source
, set_layer_type_face
and set_layer_type_sequence
should be hidden or be homogenized ? Some of them return self
other return self._type
.
If possible I would hidde them if that can be set in the init through some parameter and if this isn't supposed to change while the object is alive.
Description
Create Sensor class
Issue linked
Checklist
feat: add optical property
)