matrice-analytics 0.1.54__py3-none-any.whl → 0.1.56__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of matrice-analytics might be problematic. Click here for more details.
- matrice_analytics/post_processing/face_reg/embedding_manager.py +84 -18
- matrice_analytics/post_processing/face_reg/face_recognition.py +5 -5
- {matrice_analytics-0.1.54.dist-info → matrice_analytics-0.1.56.dist-info}/METADATA +1 -1
- {matrice_analytics-0.1.54.dist-info → matrice_analytics-0.1.56.dist-info}/RECORD +7 -7
- {matrice_analytics-0.1.54.dist-info → matrice_analytics-0.1.56.dist-info}/WHEEL +0 -0
- {matrice_analytics-0.1.54.dist-info → matrice_analytics-0.1.56.dist-info}/licenses/LICENSE.txt +0 -0
- {matrice_analytics-0.1.54.dist-info → matrice_analytics-0.1.56.dist-info}/top_level.txt +0 -0
|
@@ -175,11 +175,14 @@ class EmbeddingManager:
|
|
|
175
175
|
"""Load all staff embeddings from API and cache them."""
|
|
176
176
|
if not self.face_client:
|
|
177
177
|
self.logger.error("Face client not available for loading staff embeddings")
|
|
178
|
+
print("ERROR: Face client not available for loading staff embeddings")
|
|
178
179
|
return False
|
|
179
180
|
|
|
180
181
|
try:
|
|
181
182
|
self.logger.info("Loading staff embeddings from API...")
|
|
183
|
+
print("=============== LOADING STAFF EMBEDDINGS FROM API ===============")
|
|
182
184
|
response = await self.face_client.get_all_staff_embeddings()
|
|
185
|
+
print(f"API RESPONSE TYPE: {type(response)}, IS_LIST: {isinstance(response, list)}, LEN: {len(response) if isinstance(response, list) else 'N/A'}")
|
|
183
186
|
|
|
184
187
|
# Robust response handling: accept dict with data or raw list
|
|
185
188
|
embeddings_data: List[Dict[str, Any]] = []
|
|
@@ -205,23 +208,58 @@ class EmbeddingManager:
|
|
|
205
208
|
|
|
206
209
|
self.staff_embeddings = []
|
|
207
210
|
embeddings_list = []
|
|
208
|
-
|
|
211
|
+
expected_dim: Optional[int] = None
|
|
212
|
+
dims_observed: List[int] = []
|
|
213
|
+
mismatch_examples: List[Tuple[str, int]] = [] # (staffId, dim)
|
|
214
|
+
|
|
209
215
|
for item in embeddings_data:
|
|
210
|
-
#
|
|
211
|
-
|
|
212
|
-
|
|
216
|
+
# Skip inactive if provided
|
|
217
|
+
if isinstance(item, dict) and item.get("isActive") is False:
|
|
218
|
+
continue
|
|
219
|
+
|
|
220
|
+
raw_emb = []
|
|
221
|
+
try:
|
|
222
|
+
raw_emb = item.get("embedding", []) if isinstance(item, dict) else []
|
|
223
|
+
except Exception:
|
|
224
|
+
raw_emb = []
|
|
225
|
+
# Record observed dimension for debugging
|
|
226
|
+
try:
|
|
227
|
+
dims_observed.append(len(raw_emb) if isinstance(raw_emb, list) else 0)
|
|
228
|
+
except Exception:
|
|
229
|
+
dims_observed.append(0)
|
|
230
|
+
|
|
231
|
+
# Validate and coerce embedding list
|
|
232
|
+
if not isinstance(raw_emb, list) or len(raw_emb) == 0:
|
|
233
|
+
continue
|
|
234
|
+
try:
|
|
235
|
+
# Ensure numeric float32 list
|
|
236
|
+
clean_emb = [float(v) for v in raw_emb]
|
|
237
|
+
except Exception:
|
|
238
|
+
continue
|
|
239
|
+
|
|
240
|
+
# Dimension consistency
|
|
241
|
+
if expected_dim is None:
|
|
242
|
+
expected_dim = len(clean_emb)
|
|
243
|
+
if len(clean_emb) != expected_dim:
|
|
244
|
+
# Collect a few examples to aid debugging
|
|
245
|
+
try:
|
|
246
|
+
mismatch_examples.append((str(item.get("staffId", "")), len(clean_emb)))
|
|
247
|
+
except Exception:
|
|
248
|
+
mismatch_examples.append(("", len(clean_emb)))
|
|
249
|
+
self.logger.warning(f"Skipping embedding with mismatched dimension: got {len(clean_emb)} expected {expected_dim}")
|
|
250
|
+
continue
|
|
251
|
+
|
|
213
252
|
staff_embedding = StaffEmbedding(
|
|
214
|
-
embedding_id=item.get("embeddingId", ""),
|
|
215
|
-
staff_id=item.get("staffId", ""),
|
|
216
|
-
embedding=
|
|
217
|
-
employee_id=str(item.get("employeeId", "")),
|
|
218
|
-
staff_details=item.get("staffDetails", {}),
|
|
219
|
-
is_active=item.get("isActive", True)
|
|
253
|
+
embedding_id=(item.get("embeddingId", "") if isinstance(item, dict) else ""),
|
|
254
|
+
staff_id=(item.get("staffId", "") if isinstance(item, dict) else ""),
|
|
255
|
+
embedding=clean_emb,
|
|
256
|
+
employee_id=str(item.get("employeeId", "")) if isinstance(item, dict) else "",
|
|
257
|
+
staff_details=(item.get("staffDetails", {}) if isinstance(item, dict) else {}),
|
|
258
|
+
is_active=(item.get("isActive", True) if isinstance(item, dict) else True)
|
|
220
259
|
)
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
embeddings_list.append(staff_embedding.embedding)
|
|
260
|
+
|
|
261
|
+
self.staff_embeddings.append(staff_embedding)
|
|
262
|
+
embeddings_list.append(clean_emb)
|
|
225
263
|
|
|
226
264
|
# Create numpy matrix for fast similarity computation (thread-safe)
|
|
227
265
|
with self._embeddings_lock:
|
|
@@ -234,12 +272,31 @@ class EmbeddingManager:
|
|
|
234
272
|
|
|
235
273
|
self.embedding_metadata = self.staff_embeddings.copy()
|
|
236
274
|
self.staff_embeddings_last_update = time.time()
|
|
237
|
-
self.logger.info(f"Successfully loaded and cached {len(self.staff_embeddings)} staff embeddings")
|
|
238
|
-
|
|
275
|
+
self.logger.info(f"Successfully loaded and cached {len(self.staff_embeddings)} staff embeddings (dim={self.embeddings_matrix.shape[1]})")
|
|
276
|
+
print(f"=============== SUCCESS: LOADED {len(self.staff_embeddings)} EMBEDDINGS, MATRIX SHAPE: {self.embeddings_matrix.shape} ===============")
|
|
277
|
+
try:
|
|
278
|
+
# Quick sanity metrics
|
|
279
|
+
row0_sum = float(np.sum(self.embeddings_matrix[0])) if self.embeddings_matrix.shape[0] > 0 else 0.0
|
|
280
|
+
row0_norm = float(np.linalg.norm(self.embeddings_matrix[0])) if self.embeddings_matrix.shape[0] > 0 else 0.0
|
|
281
|
+
print(f"SANITY CHECK: row0_sum={row0_sum:.4f}, row0_norm={row0_norm:.4f} (should be ~1.0 after normalization)")
|
|
282
|
+
self.logger.debug(f"Embeddings matrix shape: {self.embeddings_matrix.shape}, dtype={self.embeddings_matrix.dtype}, row0_sum={row0_sum:.4f}")
|
|
283
|
+
except Exception as e:
|
|
284
|
+
print(f"ERROR in sanity check: {e}")
|
|
239
285
|
return True
|
|
240
286
|
else:
|
|
241
|
-
|
|
242
|
-
|
|
287
|
+
# Build diagnostics and raise to stop pipeline early with actionable info
|
|
288
|
+
dims_summary: Dict[int, int] = {}
|
|
289
|
+
for d in dims_observed:
|
|
290
|
+
dims_summary[d] = dims_summary.get(d, 0) + 1
|
|
291
|
+
error_msg = (
|
|
292
|
+
f"No valid staff embeddings loaded. Observed dimension distribution: {dims_summary}. "
|
|
293
|
+
f"Expected_dim={expected_dim}. Mismatch examples (staffId, dim): {mismatch_examples[:5]}"
|
|
294
|
+
)
|
|
295
|
+
self.logger.error(error_msg)
|
|
296
|
+
print(f"=============== ERROR: NO VALID EMBEDDINGS ===============")
|
|
297
|
+
print(f"ERROR: {error_msg}")
|
|
298
|
+
print(f"=============== STOPPING PIPELINE ===============")
|
|
299
|
+
raise RuntimeError(f"Failed to load staff embeddings due to dimension mismatch. Observed dims: {dims_summary}")
|
|
243
300
|
|
|
244
301
|
except Exception as e:
|
|
245
302
|
self.logger.error(f"Error loading staff embeddings: {e}", exc_info=True)
|
|
@@ -281,6 +338,7 @@ class EmbeddingManager:
|
|
|
281
338
|
"""Find best matching staff member using optimized matrix operations (thread-safe)."""
|
|
282
339
|
with self._embeddings_lock:
|
|
283
340
|
if self.embeddings_matrix is None or len(self.embedding_metadata) == 0:
|
|
341
|
+
print(f"ERROR: _find_best_local_match - embeddings_matrix is None={self.embeddings_matrix is None}, metadata_len={len(self.embedding_metadata)}")
|
|
284
342
|
return None
|
|
285
343
|
|
|
286
344
|
# Create local copies to avoid issues with concurrent modifications
|
|
@@ -292,6 +350,11 @@ class EmbeddingManager:
|
|
|
292
350
|
|
|
293
351
|
try:
|
|
294
352
|
query_array = np.array(query_embedding, dtype=np.float32).reshape(1, -1)
|
|
353
|
+
# Dimension check
|
|
354
|
+
if embeddings_matrix.shape[1] != query_array.shape[1]:
|
|
355
|
+
self.logger.warning(f"Query embedding dim mismatch: query={query_array.shape[1]} staff={embeddings_matrix.shape[1]}")
|
|
356
|
+
print(f"ERROR: DIMENSION MISMATCH - query={query_array.shape[1]} staff={embeddings_matrix.shape[1]}")
|
|
357
|
+
return None
|
|
295
358
|
|
|
296
359
|
# Normalize query embedding
|
|
297
360
|
query_norm = np.linalg.norm(query_array)
|
|
@@ -327,6 +390,9 @@ class EmbeddingManager:
|
|
|
327
390
|
return 0.0
|
|
328
391
|
try:
|
|
329
392
|
query_array = np.array(query_embedding, dtype=np.float32).reshape(1, -1)
|
|
393
|
+
if embeddings_matrix.shape[1] != query_array.shape[1]:
|
|
394
|
+
print(f"ERROR: get_best_similarity DIMENSION MISMATCH - query={query_array.shape[1]} staff={embeddings_matrix.shape[1]}")
|
|
395
|
+
return 0.0
|
|
330
396
|
qn = np.linalg.norm(query_array)
|
|
331
397
|
if qn == 0:
|
|
332
398
|
return 0.0
|
|
@@ -1603,11 +1603,11 @@ class FaceRecognitionEmbeddingUseCase(BaseProcessor):
|
|
|
1603
1603
|
human_text_lines.append(f"\tRecognized: {face_summary.get('session_totals',{}).get('total_recognized', 0)}")
|
|
1604
1604
|
human_text_lines.append(f"\tUnknown: {face_summary.get('session_totals',{}).get('total_unknown', 0)}")
|
|
1605
1605
|
# Additional counts similar to compare_similarity HUD
|
|
1606
|
-
try:
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
except Exception:
|
|
1610
|
-
|
|
1606
|
+
# try:
|
|
1607
|
+
# human_text_lines.append(f"\tCurrent Faces (detections): {total_detections}")
|
|
1608
|
+
# human_text_lines.append(f"\tTotal Unique Tracks: {cumulative_total}")
|
|
1609
|
+
# except Exception:
|
|
1610
|
+
# pass
|
|
1611
1611
|
|
|
1612
1612
|
human_text = "\n".join(human_text_lines)
|
|
1613
1613
|
|
|
@@ -28,8 +28,8 @@ matrice_analytics/post_processing/core/config.py,sha256=uyxWndO-DE9PeGD_h5K3TeB0
|
|
|
28
28
|
matrice_analytics/post_processing/core/config_utils.py,sha256=QuAS-_JKSoNOtfUWgr7Alf_wsqODzN2rHlQu-cHRK0s,34311
|
|
29
29
|
matrice_analytics/post_processing/face_reg/__init__.py,sha256=yntaiGlW9vdjBpPZQXNuovALihJPzRlFyUE88l3MhBA,1364
|
|
30
30
|
matrice_analytics/post_processing/face_reg/compare_similarity.py,sha256=NlFc8b2a74k0PqSFAbuM_fUbA1BT3pr3VUgvSqRpJzQ,23396
|
|
31
|
-
matrice_analytics/post_processing/face_reg/embedding_manager.py,sha256=
|
|
32
|
-
matrice_analytics/post_processing/face_reg/face_recognition.py,sha256=
|
|
31
|
+
matrice_analytics/post_processing/face_reg/embedding_manager.py,sha256=euZdFxslvEStli7pcUrBhyvJ-FR5uUGjU7HkrQ2XIfU,41940
|
|
32
|
+
matrice_analytics/post_processing/face_reg/face_recognition.py,sha256=CkJaf1M4Ah7YSoxOjSVoSPqAp912QkrVS0v2cLeWMCQ,103595
|
|
33
33
|
matrice_analytics/post_processing/face_reg/face_recognition_client.py,sha256=eF2NYju1uWKXhILndI1rh4_VhWrKSGidui2jjbPQXgM,27596
|
|
34
34
|
matrice_analytics/post_processing/face_reg/people_activity_logging.py,sha256=vZbIvkK1h3h58ROeF0_ygF3lqr19O2h5222bN8XyIis,13675
|
|
35
35
|
matrice_analytics/post_processing/ocr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -189,8 +189,8 @@ matrice_analytics/post_processing/utils/format_utils.py,sha256=UTF7A5h9j0_S12xH9
|
|
|
189
189
|
matrice_analytics/post_processing/utils/geometry_utils.py,sha256=BWfdM6RsdJTTLR1GqkWfdwpjMEjTCJyuBxA4zVGKdfk,9623
|
|
190
190
|
matrice_analytics/post_processing/utils/smoothing_utils.py,sha256=78U-yucAcjUiZ0NIAc9NOUSIT0PWP1cqyIPA_Fdrjp0,14699
|
|
191
191
|
matrice_analytics/post_processing/utils/tracking_utils.py,sha256=rWxuotnJ3VLMHIBOud2KLcu4yZfDp7hVPWUtNAq_2xw,8288
|
|
192
|
-
matrice_analytics-0.1.
|
|
193
|
-
matrice_analytics-0.1.
|
|
194
|
-
matrice_analytics-0.1.
|
|
195
|
-
matrice_analytics-0.1.
|
|
196
|
-
matrice_analytics-0.1.
|
|
192
|
+
matrice_analytics-0.1.56.dist-info/licenses/LICENSE.txt,sha256=_uQUZpgO0mRYL5-fPoEvLSbNnLPv6OmbeEDCHXhK6Qc,1066
|
|
193
|
+
matrice_analytics-0.1.56.dist-info/METADATA,sha256=plXBTb5-QrbiN9-4ui3W5hj6bo15-ka3tgANA0Pxzpk,14378
|
|
194
|
+
matrice_analytics-0.1.56.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
195
|
+
matrice_analytics-0.1.56.dist-info/top_level.txt,sha256=STAPEU-e-rWTerXaspdi76T_eVRSrEfFpURSP7_Dt8E,18
|
|
196
|
+
matrice_analytics-0.1.56.dist-info/RECORD,,
|
|
File without changes
|
{matrice_analytics-0.1.54.dist-info → matrice_analytics-0.1.56.dist-info}/licenses/LICENSE.txt
RENAMED
|
File without changes
|
|
File without changes
|