services/app.service.ts
Entrypoint to store for disaggregation application.
SharedService
Properties |
|
Methods |
|
Accessors |
constructor(formBuilder: FormBuilder, spinnerService: SpinnerService, nshmpService: NshmpService, hazardService: HazardService, route: ActivatedRoute, http: HttpClient, location: LocationService, localId: string)
|
|||||||||||||||||||||||||||
Defined in services/app.service.ts:79
|
|||||||||||||||||||||||||||
Parameters :
|
Private addRequiredValidator | ||||||
addRequiredValidator(control: AbstractControl)
|
||||||
Defined in services/app.service.ts:467
|
||||||
Parameters :
Returns :
void
|
addValidators |
addValidators()
|
Defined in services/app.service.ts:166
|
Returns :
void
|
Private callFaultsService |
callFaultsService()
|
Defined in services/app.service.ts:471
|
Returns :
void
|
Private callFeaturesUsage$ |
callFeaturesUsage$()
|
Defined in services/app.service.ts:484
|
Check if FAULT is available.
Returns :
Observable<void>
|
callService |
callService()
|
Defined in services/app.service.ts:207
|
Returns :
void
|
Private componentDataToCSV | ||||||||||||||||||||
componentDataToCSV(componentData: DisaggComponentData, formValues: DisaggControlForm, showMetadata)
|
||||||||||||||||||||
Defined in services/app.service.ts:506
|
||||||||||||||||||||
Convert disaggregation component data to CSV.
Parameters :
Returns :
string
|
Private contributorsToCSV | ||||||||||||||||||||
contributorsToCSV(sources: DisaggSource[], formValues: DisaggControlForm, showMetadata)
|
||||||||||||||||||||
Defined in services/app.service.ts:549
|
||||||||||||||||||||
Convert disaggregation contributions to CSV.
Parameters :
Returns :
string
|
defaultFormValues |
defaultFormValues()
|
Defined in services/app.service.ts:251
|
Returns the default form values.
Returns :
DisaggControlForm
|
init |
init()
|
Defined in services/app.service.ts:267
|
Initialize applicaiton.
Returns :
void
|
Private initialFormSet |
initialFormSet()
|
Defined in services/app.service.ts:580
|
Returns :
void
|
initialState |
initialState()
|
Defined in services/app.service.ts:302
|
Disagg app initial state
Returns :
AppState
|
Private maxDirectionSupported | ||||||||
maxDirectionSupported(state: DisaggControlForm)
|
||||||||
Defined in services/app.service.ts:632
|
||||||||
Determines whether the current form state allows for max-direction scaling. has a max-direction factor
Parameters :
Returns :
boolean
true if the selected disagg target is IML and the selected IMT has a max-direction factor |
Private metadataCSV | ||||||||
metadataCSV(formValues: DisaggControlForm)
|
||||||||
Defined in services/app.service.ts:644
|
||||||||
Returns the metadata in CSV.
Parameters :
Returns :
string
|
Private metadataText | ||||||
metadataText(formValues: DisaggControlForm)
|
||||||
Defined in services/app.service.ts:653
|
||||||
Parameters :
Returns :
string
|
onDisaggTarget |
onDisaggTarget()
|
Defined in services/app.service.ts:324
|
Returns :
void
|
resetControlPanel |
resetControlPanel()
|
Defined in services/app.service.ts:341
|
Reset the control panel.
Returns :
void
|
resetState |
resetState()
|
Defined in services/app.service.ts:346
|
Returns :
void
|
saveComponentData |
saveComponentData()
|
Defined in services/app.service.ts:363
|
Save the component data.
Returns :
void
|
saveComponentSummaryReport |
saveComponentSummaryReport()
|
Defined in services/app.service.ts:376
|
Returns :
void
|
saveContributions | ||||||||||||
saveContributions(data: DisaggComponentData, formValues: DisaggControlForm)
|
||||||||||||
Defined in services/app.service.ts:393
|
||||||||||||
Save the contributions.
Parameters :
Returns :
void
|
saveSummary | ||||||||||||
saveSummary(data: DisaggComponentData, formValues: DisaggControlForm)
|
||||||||||||
Defined in services/app.service.ts:409
|
||||||||||||
Save the summary.
Parameters :
Returns :
void
|
saveSummaryReport |
saveSummaryReport()
|
Defined in services/app.service.ts:416
|
Returns :
void
|
Private serviceEndpoint | ||||||||||||
serviceEndpoint(serviceUrl: string, values: DisaggControlForm)
|
||||||||||||
Defined in services/app.service.ts:683
|
||||||||||||
Build the URL to call the appropriate backend service with the given values. (should not have a trailing slash)
Parameters :
Returns :
string
the service call URL |
setLocation | ||||||||
setLocation(location: Location)
|
||||||||
Defined in services/app.service.ts:433
|
||||||||
Set the location form fields.
Parameters :
Returns :
void
|
Private summaryReportText | ||||||||||||
summaryReportText(componentData: DisaggComponentData, showMetadata)
|
||||||||||||
Defined in services/app.service.ts:707
|
||||||||||||
Parameters :
Returns :
string
|
Private summaryToText | ||||||||||||||||||||
summaryToText(summaries: DisaggSummary[], formValues: DisaggControlForm, showMetadata)
|
||||||||||||||||||||
Defined in services/app.service.ts:734
|
||||||||||||||||||||
Convert the disaggregation summaries to text.
Parameters :
Returns :
string
|
updateComponentData |
updateComponentData()
|
Defined in services/app.service.ts:440
|
Returns :
void
|
Private updateDisaggData |
updateDisaggData()
|
Defined in services/app.service.ts:753
|
Returns :
void
|
updateState | ||||||
updateState(state: Partial<AppState>)
|
||||||
Defined in services/app.service.ts:453
|
||||||
Parameters :
Returns :
void
|
Private updateUrl |
updateUrl()
|
Defined in services/app.service.ts:764
|
Returns :
void
|
Private updateUsageUrl |
updateUsageUrl()
|
Defined in services/app.service.ts:771
|
Returns :
void
|
Private endpoint |
Default value : this.nshmpHazWs.services.curveServices.disagg
|
Defined in services/app.service.ts:72
|
Disaggregation endpoint |
Private featuresEndpoint |
Default value : this.nshmpHazWs.services.curveServices.features
|
Defined in services/app.service.ts:74
|
Features endpoint |
Readonly formGroup |
Default value : this.formBuilder.group<DisaggControlForm>(
this.defaultFormValues(),
)
|
Defined in services/app.service.ts:76
|
Private nshmpHazWs |
Default value : environment.webServices.nshmpHazWs
|
Defined in services/app.service.ts:70
|
nshmp-haz-ws web config |
Readonly state |
Default value : signal<AppState>(this.initialState())
|
Defined in services/app.service.ts:79
|
availableModels |
getavailableModels()
|
Defined in services/app.service.ts:103
|
Returns the available models.
Returns :
Signal<Parameter[]>
|
componentData |
getcomponentData()
|
Defined in services/app.service.ts:110
|
Returns the disagg response values observable.
Returns :
Signal<DisaggComponentData>
|
disaggData |
getdisaggData()
|
Defined in services/app.service.ts:117
|
Returns the disaggregation data observable.
Returns :
Signal<DisaggResponseDataValues>
|
faults |
getfaults()
|
Defined in services/app.service.ts:121
|
nshmService |
getnshmService()
|
Defined in services/app.service.ts:128
|
Returns the metadata of the NSHM observable.
Returns :
Signal<NshmMetadata>
|
responseMetadata |
getresponseMetadata()
|
Defined in services/app.service.ts:139
|
Returns the response metadata observable.
Returns :
Signal<DisaggResponseMetadata>
|
serviceCallInfo |
getserviceCallInfo()
|
Defined in services/app.service.ts:146
|
Returns the service call info.
Returns :
Signal<ServiceCallInfo>
|
serviceResponse |
getserviceResponse()
|
Defined in services/app.service.ts:153
|
Returns the disagg response.
Returns :
Signal<DisaggResponse>
|
usage |
getusage()
|
Defined in services/app.service.ts:160
|
Return the disagg usage.
Returns :
Signal<DisaggUsage>
|
import {Location as LocationService} from '@angular/common';
import {HttpClient, HttpParams} from '@angular/common/http';
import {
computed,
Inject,
Injectable,
LOCALE_ID,
Signal,
signal,
} from '@angular/core';
import {AbstractControl, FormBuilder, Validators} from '@angular/forms';
import {ActivatedRoute} from '@angular/router';
import {
DisaggControlForm,
DisaggTarget,
FormatLatitudePipe,
FormatLongitudePipe,
HazardService,
hazardUtils,
ReturnPeriodPipe,
} from '@ghsc/nshmp-lib-ng/hazard';
import {
NshmpService,
nshmpUtils,
RETURN_PERIOD_BOUNDS,
ReturnPeriod,
ServiceCallInfo,
SpinnerService,
} from '@ghsc/nshmp-lib-ng/nshmp';
import {
DisaggComponentData,
DisaggRequestMetadata,
DisaggResponse,
DisaggResponseDataValues,
DisaggResponseMetadata,
DisaggSource,
DisaggSummary,
DisaggUsage,
} from '@ghsc/nshmp-utils-ts/libs/nshmp-haz/www/disagg-service';
import {
FeaturesUsageResponse,
FeatureType,
} from '@ghsc/nshmp-utils-ts/libs/nshmp-haz/www/features-service';
import {NshmMetadata} from '@ghsc/nshmp-utils-ts/libs/nshmp-haz/www/nshm-service';
import {Location} from '@ghsc/nshmp-utils-ts/libs/nshmp-lib/geo';
import {Imt} from '@ghsc/nshmp-utils-ts/libs/nshmp-lib/gmm';
import {NshmId} from '@ghsc/nshmp-utils-ts/libs/nshmp-lib/nshm';
import {Parameter} from '@ghsc/nshmp-utils-ts/libs/nshmp-ws-utils/metadata';
import deepEqual from 'deep-equal';
import {environment} from 'projects/nshmp-apps/src/environments/environment';
import {AppServiceModel} from 'projects/nshmp-apps/src/shared/models/app-service.model';
import {SharedService} from 'projects/nshmp-apps/src/shared/services/shared.service';
import {apps} from 'projects/nshmp-apps/src/shared/utils/applications.utils';
import {catchError, forkJoin, map, Observable} from 'rxjs';
import {DisaggQuery} from '../models/disagg-query.model';
import {AppState} from '../models/state.model';
/**
* Entrypoint to store for disaggregation application.
*/
@Injectable({
providedIn: 'root',
})
export class AppService
extends SharedService
implements AppServiceModel<AppState, DisaggControlForm>
{
/** nshmp-haz-ws web config */
private nshmpHazWs = environment.webServices.nshmpHazWs;
/** Disaggregation endpoint */
private endpoint = this.nshmpHazWs.services.curveServices.disagg;
/** Features endpoint */
private featuresEndpoint = this.nshmpHazWs.services.curveServices.features;
readonly formGroup = this.formBuilder.group<DisaggControlForm>(
this.defaultFormValues(),
);
readonly state = signal<AppState>(this.initialState());
constructor(
private formBuilder: FormBuilder,
private spinnerService: SpinnerService,
private nshmpService: NshmpService,
private hazardService: HazardService,
private route: ActivatedRoute,
private http: HttpClient,
private location: LocationService,
@Inject(LOCALE_ID) private localId: string,
) {
super();
this.addValidators();
this.formGroup.controls.disaggComponent.disable();
this.formGroup.controls.disaggComponent.valueChanges.subscribe(() =>
this.updateComponentData(),
);
}
/**
* Returns the available models.
*/
get availableModels(): Signal<Parameter[]> {
return computed(() => this.state().availableModels);
}
/**
* Returns the disagg response values observable.
*/
get componentData(): Signal<DisaggComponentData> {
return computed(() => this.state().componentData);
}
/**
* Returns the disaggregation data observable.
*/
get disaggData(): Signal<DisaggResponseDataValues> {
return computed(() => this.state().disaggData);
}
get faults(): Signal<GeoJSON.FeatureCollection> {
return computed(() => this.state().faults);
}
/**
* Returns the metadata of the NSHM observable.
*/
get nshmService(): Signal<NshmMetadata> {
return computed(() =>
this.state().nshmServices.find(
nshmService => nshmService.model === this.formGroup.getRawValue().model,
),
);
}
/**
* Returns the response metadata observable.
*/
get responseMetadata(): Signal<DisaggResponseMetadata> {
return computed(() => this.state().serviceResponse?.response.metadata);
}
/**
* Returns the service call info.
*/
get serviceCallInfo(): Signal<ServiceCallInfo> {
return computed(() => this.state().serviceCallInfo);
}
/**
* Returns the disagg response.
*/
get serviceResponse(): Signal<DisaggResponse> {
return computed(() => this.state().serviceResponse);
}
/**
* Return the disagg usage.
*/
get usage(): Signal<DisaggUsage> {
return computed(() =>
this.state().usageResponses?.get(this.formGroup.getRawValue().model),
);
}
addValidators(): void {
const controls = this.formGroup.controls;
this.addRequiredValidator(controls.imt);
this.addRequiredValidator(controls.latitude);
this.addRequiredValidator(controls.longitude);
this.addRequiredValidator(controls.model);
this.addRequiredValidator(controls.siteClass);
this.addRequiredValidator(controls.vs30);
controls.iml.addValidators([
control => {
if (this.formGroup.getRawValue().disaggTarget === DisaggTarget.IML) {
return Validators.required(control);
} else {
return Validators.nullValidator(control);
}
},
]);
controls.returnPeriod.addValidators([
control => {
if (
this.formGroup.getRawValue().disaggTarget ===
DisaggTarget.RETURN_PERIOD
) {
return Validators.required(control);
} else {
return Validators.nullValidator(control);
}
},
Validators.min(RETURN_PERIOD_BOUNDS.min),
Validators.max(RETURN_PERIOD_BOUNDS.max),
]);
controls.latitude.addValidators(this.validateNan());
controls.longitude.addValidators(this.validateNan());
this.formGroup.updateValueAndValidity();
}
callService(): void {
const spinnerRef = this.spinnerService.show(
`${SpinnerService.MESSAGE_SERVICE}
<br>
(Could take 30+ seconds)
`,
);
const values = this.formGroup.getRawValue();
const service = this.nshmService();
const serviceUrl = `${service.url}${this.endpoint}`;
const url = this.serviceEndpoint(serviceUrl, values);
forkJoin([
this.nshmpService.callService$<DisaggResponse>(url),
this.callFeaturesUsage$(),
])
.pipe(
catchError((error: Error) => {
spinnerRef.close();
return this.nshmpService.throwError$(error);
}),
)
.subscribe(([serviceResponse]) => {
spinnerRef.close();
this.updateState({
serviceCallInfo: {
...this.state().serviceCallInfo,
serviceCalls: [url],
},
serviceResponse,
});
this.updateComponentData();
this.updateDisaggData();
this.formGroup.controls.disaggComponent.enable();
});
}
/**
* Returns the default form values.
*/
defaultFormValues(): DisaggControlForm {
return {
...hazardUtils.hazardDefaultFormValues(),
commonReturnPeriods: ReturnPeriod.RP_2475,
disaggComponent: 'Total',
disaggTarget: DisaggTarget.RETURN_PERIOD,
iml: null,
imt: Imt.PGA,
maxDirection: false,
vs30: 760,
};
}
/**
* Initialize applicaiton.
*/
init(): void {
const spinnerRef = this.spinnerService.show(
SpinnerService.MESSAGE_METADATA,
);
const service = environment.webServices.nshmpHazWs;
const endpoint = service.services.curveServices.disagg;
this.hazardService
.dynamicNshms$<DisaggRequestMetadata>(
`${service.url}${service.services.nshms}`,
endpoint,
)
.pipe(
catchError((error: Error) => {
spinnerRef.close();
return this.nshmpService.throwError$(error);
}),
)
.subscribe(({models, nshmServices, usageResponses}) => {
spinnerRef.close();
this.updateState({
availableModels: models,
nshmServices,
usageResponses,
});
this.updateUsageUrl();
this.initialFormSet();
});
}
/**
* Disagg app initial state
*/
initialState(): AppState {
const usageResponses: Map<string, DisaggUsage> = new Map();
usageResponses.set(NshmId.CONUS_2018, null);
return {
availableModels: [],
componentData: null,
disaggData: null,
faults: null,
nshmServices: [],
plots: null,
responseSpectra: null,
serviceCallInfo: {
serviceCalls: [],
serviceName: 'Disaggregation',
usage: [],
},
serviceResponse: null,
usageResponses,
};
}
onDisaggTarget(): void {
if (this.formGroup.getRawValue().disaggTarget === DisaggTarget.IML) {
this.formGroup.controls.returnPeriod.disable();
this.formGroup.controls.commonReturnPeriods.disable();
this.formGroup.controls.iml.enable();
this.formGroup.controls.maxDirection.enable();
} else {
this.formGroup.controls.returnPeriod.enable();
this.formGroup.controls.commonReturnPeriods.enable();
this.formGroup.controls.iml.disable();
this.formGroup.controls.maxDirection.disable();
}
}
/**
* Reset the control panel.
*/
resetControlPanel(): void {
this.formGroup.reset(this.defaultFormValues());
this.resetState();
}
resetState(): void {
this.updateState({
faults: null,
plots: this.initialState().plots,
serviceCallInfo: {
...this.state().serviceCallInfo,
serviceCalls: [],
},
serviceResponse: null,
});
this.formGroup.controls.disaggComponent.disable();
this.updateUsageUrl();
}
/**
* Save the component data.
*/
saveComponentData(): void {
const data = this.componentData();
const blob = new Blob(
[this.componentDataToCSV(data, this.formGroup.getRawValue())],
{
type: 'text/csv;charset=utf-8;',
},
);
this.nshmpService.saveAs(blob, `disagg-${data.component}.csv`);
}
saveComponentSummaryReport(): void {
const blob = new Blob([this.summaryReportText(this.componentData())], {
type: 'text/csv;charset=utf-8;',
});
this.nshmpService.saveAs(
blob,
`disagg-summary-${this.componentData().component}.txt`,
);
}
/**
* Save the contributions.
*
* @param data The component data
* @param formValues The form values
*/
saveContributions(
data: DisaggComponentData,
formValues: DisaggControlForm,
): void {
const blob = new Blob([this.contributorsToCSV(data.sources, formValues)], {
type: 'text/csv;charset=utf-8;',
});
this.nshmpService.saveAs(blob, `disagg-sources-${data.component}.csv`);
}
/**
* Save the summary.
*
* @param data The component data
* @param formValues The form values
*/
saveSummary(data: DisaggComponentData, formValues: DisaggControlForm): void {
const blob = new Blob([this.summaryToText(data.summary, formValues)], {
type: 'text/csv;charset=utf-8;',
});
this.nshmpService.saveAs(blob, `disagg-summary-${data.component}.txt`);
}
saveSummaryReport(): void {
const summaries = this.disaggData().data.map((data, index) =>
this.summaryReportText(data, index === 0),
);
const blob = new Blob(summaries, {
type: 'text/csv;charset=utf-8',
});
this.nshmpService.saveAs(blob, 'dissag-summary.txt');
}
/**
* Set the location form fields.
*
* @param location The location
*/
setLocation(location: Location): void {
this.formGroup.patchValue({
latitude: location.latitude,
longitude: location.longitude,
});
}
updateComponentData(): void {
this.updateDisaggData();
const componentData = this.disaggData()?.data.find(
disagg =>
disagg.component === this.formGroup.getRawValue().disaggComponent,
);
this.updateState({
componentData,
});
}
updateState(state: Partial<AppState>): void {
const updatedState = {
...this.state(),
...state,
};
if (!deepEqual(updatedState, this.state())) {
this.state.set({
...this.state(),
...state,
});
}
}
private addRequiredValidator(control: AbstractControl): void {
control.addValidators(control => Validators.required(control));
}
private callFaultsService(): void {
const url = `${this.nshmService().url}${this.featuresEndpoint}/${FeatureType.FAULT}/true`;
this.http.get<GeoJSON.FeatureCollection>(url).subscribe(faults => {
this.updateState({
faults,
});
});
}
/**
* Check if FAULT is available.
*/
private callFeaturesUsage$(): Observable<void> {
const url = `${this.nshmService().url}${this.featuresEndpoint}`;
return this.http.get<FeaturesUsageResponse>(url).pipe(
map(featureUsage => {
const featureTypes = featureUsage.response.featureType.map(
feature => feature.value,
);
if (featureTypes.includes(FeatureType.FAULT)) {
this.callFaultsService();
}
}),
);
}
/**
* Convert disaggregation component data to CSV.
*
* @param componentData Disaggregation component data
* @param formValues Form values
*/
private componentDataToCSV(
componentData: DisaggComponentData,
formValues: DisaggControlForm,
showMetadata = true,
): string {
const metadata = this.serviceResponse().response.metadata;
const bins = metadata.εbins;
const keys = componentData.summary.find(
data => data.name.toLowerCase() === 'epsilon keys',
);
const headers = [
'Distance (km)',
'Magnitude (Mw)',
'ε total',
...keys.data.map(data => data.name),
];
const csv = componentData.data.map(data => {
const εvalues = bins.map(
bin => data.εdata.find(data => data.εbin === bin.id)?.value ?? 0.0,
);
const sum = εvalues.reduce((a, b) => a + b, 0);
const values = [sum, ...εvalues]
.map(num => num.toExponential(3))
.join(', ');
return `${data.r}, ${data.m}, ${values}`;
});
const table = `${headers.join(', ')}\n${csv.join('\n')}`;
return showMetadata
? `${this.metadataCSV(formValues)}\n\n\n` + table
: table;
}
/**
* Convert disaggregation contributions to CSV.
*
* @param sources Disaggregation sources
* @param formValues Form values
*/
private contributorsToCSV(
sources: DisaggSource[],
formValues: DisaggControlForm,
showMetadata = true,
): string {
const label = 'Disaggregation Contributions';
if (sources === null || sources.length === 0) {
return `${label}: N/A\n\n`;
}
const headers = 'Source Set ↳ Source, Type, r, m, ε0, lon, lat, az, %';
const csv = sources
.map(source => {
const name =
source.type === 'SINGLE' ? `\t\t${source.name}` : source.name;
return (
`"${name}", ${source.type}, ${source.r}, ${source.m}, ${source.ε}, ` +
`${source.longitude}, ${source.latitude}, ${source.azimuth}, ${source.contribution}\n`
);
})
.map(source => source.replace(/null/gi, ''))
.join('');
const table = `${label}\n${headers}\n ${csv}\n\n`;
return showMetadata
? `${this.metadataCSV(formValues)}\n\n ${table}`
: table;
}
private initialFormSet(): void {
const query = this.route.snapshot.queryParams as DisaggQuery;
const defaultValues = this.defaultFormValues();
const formValues: DisaggControlForm = {
commonReturnPeriods: defaultValues.commonReturnPeriods,
disaggComponent: query.disaggComponent
? query.disaggComponent
: defaultValues.disaggComponent,
disaggTarget:
DisaggTarget[query.disaggTarget] ?? defaultValues.disaggTarget,
iml: query.iml ? Number.parseFloat(query.iml) : defaultValues.iml,
imt: query.imt ? query.imt : defaultValues.imt,
latitude: query.latitude
? Number.parseFloat(query.latitude)
: defaultValues.latitude,
longitude: query.longitude
? Number.parseFloat(query.longitude)
: defaultValues.longitude,
maxDirection: query.maxDirection
? query.maxDirection === 'true'
: defaultValues.maxDirection,
model: query.model ? query.model : defaultValues.model,
returnPeriod: query.returnPeriod
? Number.parseInt(query.returnPeriod, 10)
: defaultValues.returnPeriod,
siteClass: query.siteClass ? query.siteClass : defaultValues.siteClass,
vs30: query.vs30 ? Number.parseFloat(query.vs30) : defaultValues.vs30,
};
formValues.maxDirection &&= this.maxDirectionSupported(formValues);
this.formGroup.patchValue(formValues);
this.onDisaggTarget();
if (this.formGroup.valid) {
this.nshmpService.selectPlotControl();
this.callService();
} else if (this.formGroup.getRawValue() !== defaultValues) {
this.formGroup.markAsDirty();
}
this.formGroup.valueChanges.subscribe(() => this.updateUrl());
}
/**
* Determines whether the current form state allows for max-direction scaling.
*
* @param state the form state
* @returns true if the selected disagg target is IML and the selected IMT
* has a max-direction factor
*/
private maxDirectionSupported(state: DisaggControlForm): boolean {
return (
state.disaggTarget === DisaggTarget.IML &&
state.imt in hazardUtils.MAX_DIRECTION
);
}
/**
* Returns the metadata in CSV.
*
* @param formValues Form values
*/
private metadataCSV(formValues: DisaggControlForm): string {
return (
'Metadata\n' +
'Model, Longitude, Latitude, IMT, Return Period, VS30\n' +
`${formValues.model}, ${formValues.longitude}, ${formValues.latitude}, ` +
`${formValues.imt}, ${formValues.returnPeriod}, ${formValues.vs30}`
);
}
private metadataText(formValues: DisaggControlForm): string {
const usage = this.usage().response;
const imt = usage.model.imts.find(
imt => imt.value === formValues.imt.toString(),
)?.display;
const vs30 =
formValues.siteClass === nshmpUtils.selectPlaceHolder().value
? `${formValues.vs30} m/s`
: `${formValues.vs30} m/s (${formValues.siteClass})`;
return (
`Model: ${usage.model.name}\n` +
`Longitude: ${new FormatLongitudePipe(this.localId).transform(formValues.longitude)} \n` +
`Latitude: ${new FormatLatitudePipe(this.localId).transform(formValues.latitude)} \n` +
`IMT: ${imt} \n` +
`Return Period: ${new ReturnPeriodPipe().transform(formValues.returnPeriod)} \n` +
`VS30: ${vs30} \n\n`
);
}
/**
* Build the URL to call the appropriate backend service with the given values.
*
* @param serviceUrl the base to add the rest of the endpoint to
* (should not have a trailing slash)
* @param values the values of the form
* @returns the service call URL
*/
private serviceEndpoint(
serviceUrl: string,
values: DisaggControlForm,
): string {
const pathBase = `${serviceUrl}/${values.longitude}/${values.latitude}/${values.vs30}`;
const queryBase = '?out=DISAGG_DATA,GMM,SOURCE';
const {disaggTarget} = values;
switch (disaggTarget) {
case DisaggTarget.IML: {
const iml =
values.maxDirection && values.imt in hazardUtils.MAX_DIRECTION
? values.iml / hazardUtils.MAX_DIRECTION[values.imt]
: values.iml;
return `${pathBase}${queryBase}&${values.imt}=${iml}`;
}
case DisaggTarget.RETURN_PERIOD: {
return `${pathBase}/${values.returnPeriod}${queryBase}&imt=${values.imt}`;
}
default:
throw new Error(`Disagg target [${values.disaggTarget}] not supported`);
}
}
private summaryReportText(
componentData: DisaggComponentData,
showMetadata = true,
): string {
const formValues = this.formGroup.getRawValue();
const firstLine = '*** Disaggregation of Seismic Hazard ***';
const metadata = showMetadata
? `${firstLine}\n\n${this.metadataText(formValues)}`
: '';
return (
metadata +
`** Disaggregation Component: ${componentData.component} **\n\n` +
this.summaryToText(componentData.summary, formValues, false) +
'\n\n' +
this.componentDataToCSV(componentData, formValues, false) +
'\n\n' +
this.contributorsToCSV(componentData.sources, formValues, false)
);
}
/**
* Convert the disaggregation summaries to text.
*
* @param summaries The disaggregation summaries
* @param formValues Form values
*/
private summaryToText(
summaries: DisaggSummary[],
formValues: DisaggControlForm,
showMetadata = true,
): string {
const text = summaries.map(summary => {
const name = summary.name;
const values = summary.data.map(data => {
const units = data.units === null ? '' : data.units;
return `\t${data.name}: ${data.value}${units}`;
});
return `${name}:\n` + values.join('\n');
});
return showMetadata
? `${this.metadataCSV(formValues)}\n\n\n` + `${text.join('\n\n')}`
: `${text.join('\n\n')}`;
}
private updateDisaggData(): void {
const disaggData = this.state().serviceResponse?.response.disaggs.find(
disagg =>
disagg.imt.value === this.formGroup.getRawValue().imt.toString(),
);
this.updateState({
disaggData,
});
}
private updateUrl(): void {
this.location.replaceState(
apps().hazard.disagg.routerLink,
new HttpParams().appendAll(this.formGroup.getRawValue()).toString(),
);
}
private updateUsageUrl() {
const nshmService = this.state().nshmServices.find(
nshm => nshm.model === this.formGroup.getRawValue().model,
);
this.updateState({
serviceCallInfo: {
...this.state().serviceCallInfo,
usage: [`${nshmService.url}${this.endpoint}`],
},
});
}
}