# 데이터 계약 micarrsim의 저장 형식은 JSON Schema Draft 2020-12와 추가 관계 검증으로 정의한다. 모든 길이는 m, 시간은 s, 주파수는 Hz다. 배열 중심이 원점이고 `+x`는 오른쪽, `+y`는 위쪽, `+z`는 배열에서 장면을 향하는 우수 좌표계를 사용한다. ## 파일 종류 - `micarrsim.array`: aperture와 마이크별 `[x, y, z]` 좌표 - `micarrsim.scene`: 음원·ambient recipe, 위치 ground truth와 로컬 asset manifest - `micarrsim.experiment`: scan plane/grid, 주파수 대역, STFT와 DAS 설정 - `micarrsim.result`: raw/display acoustic map, 복수 peak와 source 매칭, 평가·성능 정보 - `micarrsim.comparison-history`: 세션의 배열별 Result 요약을 모은 편의 export. core schema 검증 대상은 아니며 각 원본 Result JSON을 대신하지 않는다. scene JSON에는 192채널 원시 sample이나 원본 asset byte를 넣지 않는다. 합성 tone/noise는 seed가 포함된 recipe로 재생성하고, 녹음 파일과 이미지는 `id`, `kind`, `fileName`, `mimeType`, `sha256` manifest로 참조한다. 사용자 컴퓨터의 절대 경로, URL, `..` 경로는 저장하지 않는다. array의 `sensitivityDb`와 `phaseOffsetDeg`는 각 마이크 수신 channel에 적용되는 편차다. 합성기는 이를 신호에 주입하고, beamformer는 알려진 calibration 값의 역 gain/phase를 적용한다. 따라서 두 값이 0이 아닌 배열도 오류 없이 조용히 무시되지 않는다. ## 로컬 asset 재연결 브라우저 보안상 Scene JSON을 새 페이지에서 열었을 때 이전 로컬 파일 권한은 복원되지 않는다. Camera는 사용자가 다시 선택한 파일을 SHA-256으로 계산해 같은 descriptor에만 연결한다. 이름이 같아도 byte가 다르면 거절하고, 원본은 브라우저 메모리에서만 decode하며 서버에 업로드하지 않는다. - 파일 하나: 최대 128 MiB - 한 Scene에 연결된 원본 파일 합계: 최대 512 MiB - 동시에 유지하는 decode 오디오 channel 합계: 최대 192 MiB Builder가 내보낸 Scene JSON과 사용한 원본 이미지·오디오는 함께 보관해야 한다. Preview WAV는 scene recipe를 mono로 합친 청취 확인용 파일이며 마이크 배열의 192채널 수신 신호가 아니다. ## 오디오와 map 정규화 `scene.mix.normalization`은 마이크 신호 합성 전에 적용할 오디오 mix 정책이다. `none`은 원래 gain을 보존하고, `peak`는 합성 전 peak를 `targetPeak`에 맞춘다. result의 `signalStats`에는 정규화 전 peak, 실제 scale, scale 적용 후에도 범위를 넘은 sample 수를 기록한다. 이는 acoustic map 표시 정규화와 별개다. result의 `rawMap`은 반드시 선형 power이고, `displayMap`은 peak-normalized 값 또는 dB 값일 수 있다. 후처리 결과는 `processedMaps`에 넣어 raw DAS map을 덮어쓰지 않는다. map은 row-major 배열이다. 첫 행은 `yMax`, 마지막 행은 `yMin`, 각 행은 `xMin`에서 `xMax` 방향이다. `values.length`는 반드시 `rows × columns`와 같아야 한다. ## Result 평가 정보 각 band의 `peaks`는 위치와 power 값, 선택적 `sourceId`, `localizationErrorM`, `localizationErrorPixels`를 저장한다. `metrics`에는 다음 유한값만 기록한다. - `peakToSidelobeDb` - `energyInsideTruthRatio` - `precision`, `recall` - `mainLobeWidthM` `evaluation`은 지표를 다시 해석할 수 있도록 truth 반경, source 매칭 tolerance, peak 검출 threshold와 최소 거리, sidelobe 제외 반경, half-power 비율, dynamic range, 최대 검출 수를 버전과 함께 저장한다. `environment`에는 실제 backend, microphone/grid 수, scan bounds와 z, 가능한 경우 GPU adapter 및 fallback 정보를 기록한다. 대역별 ground truth는 tone의 주파수가 band 안에 있을 때 그 tone source를 포함한다. noise와 asset source는 현재 모든 band의 truth로 간주한다. 즉 녹음 asset의 실제 spectrum energy를 대역별로 판정하는 계약은 아직 없으며, 이 가정은 실제 데이터 결과를 해석할 때 고려해야 한다. ## 재현성 hash `result.inputHash`는 실행에 사용한 `{ array, scene, experiment }`를 객체 key 사전순으로 재귀 정렬하고 공백 없이 JSON 직렬화한 UTF-8 byte의 SHA-256 소문자 hex다. 사용한 asset은 실행 전에 SHA-256을 계산해 scene의 해당 asset `sha256` 필드를 채운 상태로 canonical input을 만든다. 따라서 파일 이름이 같아도 내용이 바뀌면 hash가 달라진다. ## 버전과 검증 현재 계약 버전은 `1.0.0`이다. 브라우저는 `packages/contracts/schema-validator.js`로 저장소의 실제 schema를 실행한 뒤 `validation.js`에서 다음 관계를 추가 검사한다. - 중복 id와 array/scene/experiment/result 참조 - asset 종류와 안전한 상대 경로 - Nyquist 및 시간·scan 범위 - map shape와 source peak 매칭 - band별 evaluation 파라미터와 허용 metric - 현재 비스트리밍 CPU backend의 512 MiB channel-buffer 예산 지원하지 않는 schemaVersion은 묵시적으로 변환하지 않고 오류로 알린다.