Skip to content

Commit 2c53f13

Browse files
ansnfernandpyansys-ci-botdependabot[bot]anskhanson
authored
feat: Added APIs saveHarmonicProfile(), saveRandomVibeProfile(), saveShockPulseProfile() and saveThermalProfile() (#641)
Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: pyansys-ci-bot <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Keith Hanson <[email protected]>
1 parent 954c39f commit 2c53f13

File tree

6 files changed

+621
-2
lines changed

6 files changed

+621
-2
lines changed

doc/changelog.d/641.added.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Feat: Added APIs saveHarmonicProfile(), saveRandomVibeProfile(), saveShockPulseProfile() and saveThermalProfile()

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ classifiers = [
2424
]
2525

2626
dependencies = [
27-
"ansys-api-sherlock==0.1.49",
27+
"ansys-api-sherlock==0.1.50",
2828
"grpcio>=1.17, <1.68.0",
2929
"protobuf>=3.20",
3030
"pydantic>=2.9.2",

src/ansys/sherlock/core/errors.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,3 +1292,15 @@ def __init__(self, message):
12921292
def __str__(self):
12931293
"""Format error message."""
12941294
return f"Export layer image error: {self.message}"
1295+
1296+
1297+
class SherlockSaveProfileError(Exception):
1298+
"""Contains the errors raised when a profile for an existing event cannot be saved."""
1299+
1300+
def __init__(self, message):
1301+
"""Initialize error message."""
1302+
self.message = message
1303+
1304+
def __str__(self):
1305+
"""Format error message."""
1306+
return f"Save profile error: {self.message}"

src/ansys/sherlock/core/lifecycle.py

Lines changed: 187 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,16 @@
3535
SherlockLoadShockProfilePulsesError,
3636
SherlockLoadThermalProfileError,
3737
SherlockNoGrpcConnectionException,
38+
SherlockSaveProfileError,
3839
)
3940
from ansys.sherlock.core.grpc_stub import GrpcStub
40-
from ansys.sherlock.core.types.lifecycle_types import ImportThermalSignalRequest
41+
from ansys.sherlock.core.types.lifecycle_types import (
42+
ImportThermalSignalRequest,
43+
SaveHarmonicProfileRequest,
44+
SaveRandomVibeProfileRequest,
45+
SaveShockPulseProfileRequest,
46+
SaveThermalProfileRequest,
47+
)
4148
from ansys.sherlock.core.utils.version_check import require_version
4249

4350

@@ -2167,3 +2174,182 @@ def import_thermal_signal(
21672174
raise SherlockNoGrpcConnectionException()
21682175

21692176
return self.stub.importThermalSignal(import_thermal_signal_request)
2177+
2178+
@require_version(261)
2179+
def save_harmonic_profile(
2180+
self, request: SaveHarmonicProfileRequest
2181+
) -> SherlockCommonService_pb2.ReturnCode:
2182+
"""Save a harmonic life cycle event profile to a .dat or .csv file.
2183+
2184+
Available Since: 2026R1
2185+
2186+
Parameters
2187+
----------
2188+
request : SaveHarmonicProfileRequest
2189+
Request object containing the information needed to save a harmonic profile.
2190+
2191+
Returns
2192+
-------
2193+
SherlockCommonService_pb2.ReturnCode
2194+
Status code of the response. 0 for success.
2195+
2196+
Examples
2197+
--------
2198+
>>> from ansys.sherlock.core.types.lifecycle_types import SaveHarmonicProfileRequest
2199+
>>> from ansys.sherlock.core.launcher import launch_sherlock
2200+
>>> sherlock = launch_sherlock()
2201+
>>> response = sherlock.lifecycle.save_harmonic_profile(
2202+
>>> SaveHarmonicProfileRequest(
2203+
>>> project="MyProject",
2204+
>>> phase_name="DurabilityPhase",
2205+
>>> event_name="Harmonic_100Hz",
2206+
>>> triaxial_axis="x",
2207+
>>> file_path="/tmp/Harmonic_100Hz.csv",
2208+
>>> )
2209+
>>> )
2210+
>>> assert response.value == 0
2211+
"""
2212+
grpc_request = request._convert_to_grpc()
2213+
2214+
if not self._is_connection_up():
2215+
raise SherlockNoGrpcConnectionException()
2216+
2217+
response = self.stub.saveHarmonicProfile(grpc_request)
2218+
2219+
# Raise error if save failed
2220+
if response.value != 0:
2221+
raise SherlockSaveProfileError(response.message)
2222+
2223+
return response
2224+
2225+
@require_version(261)
2226+
def save_random_vibe_profile(
2227+
self, request: SaveRandomVibeProfileRequest
2228+
) -> SherlockCommonService_pb2.ReturnCode:
2229+
"""Save a random vibe life cycle event profile to a .dat or .csv file.
2230+
2231+
Available Since: 2026R1
2232+
2233+
Parameters
2234+
----------
2235+
request : SaveRandomVibeProfileRequest
2236+
Request object containing the information needed to save a random vibe profile.
2237+
2238+
Returns
2239+
-------
2240+
SherlockCommonService_pb2.ReturnCode
2241+
Status code of the response. 0 for success.
2242+
2243+
Examples
2244+
--------
2245+
>>> from ansys.sherlock.core.types.lifecycle_types import SaveRandomVibeProfileRequest
2246+
>>> from ansys.sherlock.core.launcher import launch_sherlock
2247+
>>> sherlock = launch_sherlock()
2248+
>>> response = sherlock.lifecycle.save_random_vibe_profile(
2249+
>>> SaveRandomVibeProfileRequest(
2250+
>>> project="MyProject",
2251+
>>> phase_name="RandomVibePhase",
2252+
>>> event_name="RV_Event_01",
2253+
>>> file_path="/tmp/RV_Event_01.dat",
2254+
>>> )
2255+
>>> )
2256+
>>> assert response.value == 0
2257+
"""
2258+
grpc_request = request._convert_to_grpc()
2259+
2260+
if not self._is_connection_up():
2261+
raise SherlockNoGrpcConnectionException()
2262+
2263+
response = self.stub.saveRandomVibeProfile(grpc_request)
2264+
2265+
# Raise error if save failed
2266+
if response.value != 0:
2267+
raise SherlockSaveProfileError(response.message)
2268+
2269+
@require_version(261)
2270+
def save_shock_pulse_profile(
2271+
self, request: SaveShockPulseProfileRequest
2272+
) -> SherlockCommonService_pb2.ReturnCode:
2273+
"""Save a shock pulse life cycle event profile to a .dat or .csv file.
2274+
2275+
Available Since: 2026R1
2276+
2277+
Parameters
2278+
----------
2279+
request : SaveShockPulseProfileRequest
2280+
Request object containing the information needed to save a shock pulse profile.
2281+
2282+
Returns
2283+
-------
2284+
SherlockCommonService_pb2.ReturnCode
2285+
Status code of the response. 0 for success.
2286+
2287+
Examples
2288+
--------
2289+
>>> from ansys.sherlock.core.types.lifecycle_types import SaveShockPulseProfileRequest
2290+
>>> from ansys.sherlock.core.launcher import launch_sherlock
2291+
>>> sherlock = launch_sherlock()
2292+
>>> response = sherlock.lifecycle.save_shock_pulse_profile(
2293+
>>> SaveShockPulseProfileRequest(
2294+
>>> project="MyProject",
2295+
>>> phase_name="ShockPhase",
2296+
>>> event_name="Pulse_200g",
2297+
>>> file_path="/tmp/Pulse_200g.csv",
2298+
>>> )
2299+
>>> )
2300+
>>> assert response.value == 0
2301+
"""
2302+
grpc_request = request._convert_to_grpc()
2303+
2304+
if not self._is_connection_up():
2305+
raise SherlockNoGrpcConnectionException()
2306+
2307+
response = self.stub.saveShockPulseProfile(grpc_request)
2308+
2309+
# Raise error if save failed
2310+
if response.value != 0:
2311+
raise SherlockSaveProfileError(response.message)
2312+
2313+
@require_version(261)
2314+
def save_thermal_profile(
2315+
self, request: SaveThermalProfileRequest
2316+
) -> SherlockCommonService_pb2.ReturnCode:
2317+
"""Save a thermal life cycle event profile to a .dat or .csv file.
2318+
2319+
Available Since: 2026R1
2320+
2321+
Parameters
2322+
----------
2323+
request : SaveThermalProfileRequest
2324+
Request object containing the information needed to save a thermal profile.
2325+
2326+
Returns
2327+
-------
2328+
SherlockCommonService_pb2.ReturnCode
2329+
Status code of the response. 0 for success.
2330+
2331+
Examples
2332+
--------
2333+
>>> from ansys.sherlock.core.types.lifecycle_types import SaveThermalProfileRequest
2334+
>>> from ansys.sherlock.core.launcher import launch_sherlock
2335+
>>> sherlock = launch_sherlock()
2336+
>>> response = sherlock.lifecycle.save_thermal_profile(
2337+
>>> SaveThermalProfileRequest(
2338+
>>> project="MyProject",
2339+
>>> phase_name="ThermalPhase",
2340+
>>> event_name="ThermalCycle_A",
2341+
>>> file_path="/tmp/ThermalCycle_A.dat",
2342+
>>> )
2343+
>>> )
2344+
>>> assert response.value == 0
2345+
"""
2346+
grpc_request = request._convert_to_grpc()
2347+
2348+
if not self._is_connection_up():
2349+
raise SherlockNoGrpcConnectionException()
2350+
2351+
response = self.stub.saveThermalProfile(grpc_request)
2352+
2353+
# Raise error if save failed
2354+
if response.value != 0:
2355+
raise SherlockSaveProfileError(response.message)

src/ansys/sherlock/core/types/lifecycle_types.py

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,133 @@ def _convert_to_grpc(self) -> SherlockLifeCycleService_pb2.ImportThermalSignalRe
122122
timeFilteringLimitUnits=self.time_filtering_limit_units,
123123
generatedCyclesLabel=self.generated_cycles_label,
124124
)
125+
126+
127+
class SaveHarmonicProfileRequest(BaseModel):
128+
"""Request to save a harmonic life cycle event profile to a .dat or .csv file."""
129+
130+
project: str
131+
"""Sherlock project name."""
132+
133+
phase_name: str
134+
"""The name of the life cycle phase this event is associated with."""
135+
136+
event_name: str
137+
"""Harmonic event name."""
138+
139+
triaxial_axis: str | None = None
140+
"""If the harmonic profile type is 'Triaxial', the axis this profile should be assigned to.
141+
Valid values are: x, y, z.
142+
"""
143+
144+
file_path: str
145+
"""Full destination path for the .dat or .csv file."""
146+
147+
@field_validator("project", "phase_name", "event_name", "file_path", "triaxial_axis")
148+
@classmethod
149+
def str_validation(cls, value: str, info: ValidationInfo):
150+
"""Validate string fields listed."""
151+
return basic_str_validator(value, info.field_name)
152+
153+
def _convert_to_grpc(self) -> SherlockLifeCycleService_pb2.SaveHarmonicProfileRequest:
154+
"""Convert to gRPC SaveHarmonicProfileRequest."""
155+
return SherlockLifeCycleService_pb2.SaveHarmonicProfileRequest(
156+
project=self.project,
157+
phaseName=self.phase_name,
158+
eventName=self.event_name,
159+
triaxialAxis=self.triaxial_axis or "",
160+
filePath=self.file_path,
161+
)
162+
163+
164+
class SaveRandomVibeProfileRequest(BaseModel):
165+
"""Request to save a random vibe life cycle event profile to a .dat or .csv file."""
166+
167+
project: str
168+
"""Sherlock project name."""
169+
170+
phase_name: str
171+
"""The name of the life cycle phase this event is associated with."""
172+
173+
event_name: str
174+
"""Random vibe event name."""
175+
176+
file_path: str
177+
"""Full destination path for the .dat or .csv file."""
178+
179+
@field_validator("project", "phase_name", "event_name", "file_path")
180+
@classmethod
181+
def str_validation(cls, value: str, info: ValidationInfo):
182+
"""Validate string fields listed."""
183+
return basic_str_validator(value, info.field_name)
184+
185+
def _convert_to_grpc(self) -> SherlockLifeCycleService_pb2.SaveRandomVibeProfileRequest:
186+
"""Convert to gRPC SaveRandomVibeProfileRequest."""
187+
return SherlockLifeCycleService_pb2.SaveRandomVibeProfileRequest(
188+
project=self.project,
189+
phaseName=self.phase_name,
190+
eventName=self.event_name,
191+
filePath=self.file_path,
192+
)
193+
194+
195+
class SaveShockPulseProfileRequest(BaseModel):
196+
"""Request to save a shock pulse life cycle event profile to a .dat or .csv file."""
197+
198+
project: str
199+
"""Sherlock project name."""
200+
201+
phase_name: str
202+
"""The name of the life cycle phase this event is associated with."""
203+
204+
event_name: str
205+
"""Shock event name."""
206+
207+
file_path: str
208+
"""Full destination path for the .dat or .csv file."""
209+
210+
@field_validator("project", "phase_name", "event_name", "file_path")
211+
@classmethod
212+
def str_validation(cls, value: str, info: ValidationInfo):
213+
"""Validate string fields listed."""
214+
return basic_str_validator(value, info.field_name)
215+
216+
def _convert_to_grpc(self) -> SherlockLifeCycleService_pb2.SaveShockPulseProfileRequest:
217+
"""Convert to gRPC SaveShockPulseProfileRequest."""
218+
return SherlockLifeCycleService_pb2.SaveShockPulseProfileRequest(
219+
project=self.project,
220+
phaseName=self.phase_name,
221+
eventName=self.event_name,
222+
filePath=self.file_path,
223+
)
224+
225+
226+
class SaveThermalProfileRequest(BaseModel):
227+
"""Request to save a thermal life cycle event profile to a .dat or .csv file."""
228+
229+
project: str
230+
"""Sherlock project name."""
231+
232+
phase_name: str
233+
"""The name of the life cycle phase this event is associated with."""
234+
235+
event_name: str
236+
"""Thermal event name."""
237+
238+
file_path: str
239+
"""Full destination path for the .dat or .csv file."""
240+
241+
@field_validator("project", "phase_name", "event_name", "file_path")
242+
@classmethod
243+
def str_validation(cls, value: str, info: ValidationInfo):
244+
"""Validate string fields listed."""
245+
return basic_str_validator(value, info.field_name)
246+
247+
def _convert_to_grpc(self) -> SherlockLifeCycleService_pb2.SaveThermalProfileRequest:
248+
"""Convert to gRPC SaveThermalProfileRequest."""
249+
return SherlockLifeCycleService_pb2.SaveThermalProfileRequest(
250+
project=self.project,
251+
phaseName=self.phase_name,
252+
eventName=self.event_name,
253+
filePath=self.file_path,
254+
)

0 commit comments

Comments
 (0)